1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019 Huawei Technologies Co., Ltd 4 */ 5 6 #include <crypto/crypto.h> 7 #include <crypto/sm2-kdf.h> 8 #include <io.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <string_ext.h> 12 #include <tee_api_types.h> 13 #include <tee/tee_cryp_utl.h> 14 #include <trace.h> 15 #include <util.h> 16 #include <utee_defines.h> 17 18 #include "acipher_helpers.h" 19 20 /* SM2 uses 256 bit unsigned integers in big endian format */ 21 #define SM2_INT_SIZE_BYTES 32 22 23 static TEE_Result 24 sm2_uncompressed_bytes_to_point(ecc_point *p, const ltc_ecc_dp *dp, 25 const uint8_t *x1y1, size_t max_size, 26 size_t *consumed) 27 { 28 uint8_t *ptr = (uint8_t *)x1y1; 29 uint8_t one[] = { 1 }; 30 int ltc_res = 0; 31 32 if (max_size < (size_t)(2 * SM2_INT_SIZE_BYTES)) 33 return TEE_ERROR_BAD_PARAMETERS; 34 35 ltc_res = mp_read_unsigned_bin(p->x, ptr, SM2_INT_SIZE_BYTES); 36 if (ltc_res != CRYPT_OK) 37 return TEE_ERROR_BAD_PARAMETERS; 38 39 ptr += SM2_INT_SIZE_BYTES; 40 41 ltc_res = mp_read_unsigned_bin(p->y, ptr, SM2_INT_SIZE_BYTES); 42 if (ltc_res != CRYPT_OK) 43 return TEE_ERROR_BAD_PARAMETERS; 44 45 ltc_res = ltc_ecc_is_point(dp, p->x, p->y); 46 if (ltc_res != CRYPT_OK) 47 return TEE_ERROR_BAD_PARAMETERS; 48 49 mp_read_unsigned_bin(p->z, one, sizeof(one)); 50 51 *consumed = 2 * SM2_INT_SIZE_BYTES + 1; /* PC */ 52 53 return TEE_SUCCESS; 54 } 55 56 /* 57 * GM/T 0003.1‒2012 Part 1 Section 4.2.9 58 * Conversion of a byte string @buf to a point @p. Makes sure @p is on the curve 59 * defined by domain parameters @dp. 60 * Note: only the uncompressed form is supported. Uncompressed and hybrid forms 61 * are TBD. 62 */ 63 static TEE_Result sm2_bytes_to_point(ecc_point *p, const ltc_ecc_dp *dp, 64 const uint8_t *buf, size_t max_size, 65 size_t *consumed) 66 { 67 uint8_t PC = 0; 68 69 if (!max_size) 70 return TEE_ERROR_BAD_PARAMETERS; 71 72 PC = buf[0]; 73 74 switch (PC) { 75 case 0x02: 76 case 0x03: 77 /* Compressed form */ 78 return TEE_ERROR_NOT_SUPPORTED; 79 case 0x04: 80 /* UNcompressed form */ 81 return sm2_uncompressed_bytes_to_point(p, dp, buf + 1, 82 max_size - 1, consumed); 83 case 0x06: 84 case 0x07: 85 /* Hybrid form */ 86 return TEE_ERROR_NOT_SUPPORTED; 87 default: 88 return TEE_ERROR_BAD_PARAMETERS; 89 } 90 91 return TEE_ERROR_GENERIC; 92 } 93 94 static bool is_zero(const uint8_t *buf, size_t size) 95 { 96 uint8_t v = 0; 97 size_t i = 0; 98 99 for (i = 0; i < size; i++) 100 v |= buf[i]; 101 102 return !v; 103 } 104 105 /* 106 * GM/T 0003.1‒2012 Part 4 Section 7.1 107 * Decryption algorithm 108 */ 109 TEE_Result sm2_ltc_pke_decrypt(struct ecc_keypair *key, const uint8_t *src, 110 size_t src_len, uint8_t *dst, size_t *dst_len) 111 { 112 TEE_Result res = TEE_SUCCESS; 113 uint8_t x2y2[64] = { }; 114 ecc_key ltc_key = { }; 115 ecc_point *C1 = NULL; 116 size_t C1_len = 0; 117 ecc_point *S = NULL; 118 ecc_point *x2y2p = NULL; 119 void *ctx = NULL; 120 int ltc_res = 0; 121 void *h = NULL; 122 int inf = 0; 123 uint8_t *t = NULL; 124 size_t C2_len = 0; 125 size_t i = 0; 126 size_t out_len = 0; 127 uint8_t *eom = NULL; 128 uint8_t u[TEE_SM3_HASH_SIZE] = { }; 129 130 /* 131 * Input buffer src is (C1 || C2 || C3) 132 * - C1 represents a point (should be on the curve) 133 * - C2 is the encrypted message 134 * - C3 is a SM3 hash 135 */ 136 137 res = ecc_populate_ltc_private_key(<c_key, key, TEE_ALG_SM2_PKE, 138 NULL); 139 if (res) 140 goto out; 141 142 /* Step B1: read and validate point C1 from encrypted message */ 143 144 C1 = ltc_ecc_new_point(); 145 if (!C1) { 146 res = TEE_ERROR_OUT_OF_MEMORY; 147 goto out; 148 } 149 150 res = sm2_bytes_to_point(C1, <c_key.dp, src, src_len, &C1_len); 151 if (res) 152 goto out; 153 154 /* Step B2: S = [h]C1 */ 155 156 if (ltc_key.dp.cofactor != 1) { 157 S = ltc_ecc_new_point(); 158 if (!S) { 159 res = TEE_ERROR_OUT_OF_MEMORY; 160 goto out; 161 } 162 163 ltc_res = mp_init_multi(&h, NULL); 164 if (ltc_res != CRYPT_OK) { 165 res = TEE_ERROR_OUT_OF_MEMORY; 166 goto out; 167 } 168 169 ltc_res = mp_set_int(h, ltc_key.dp.cofactor); 170 if (ltc_res != CRYPT_OK) { 171 res = TEE_ERROR_BAD_STATE; 172 goto out; 173 } 174 175 ltc_res = ltc_ecc_mulmod(h, C1, S, ltc_key.dp.A, 176 ltc_key.dp.prime, 1); 177 if (ltc_res != CRYPT_OK) { 178 res = TEE_ERROR_BAD_STATE; 179 goto out; 180 } 181 182 ltc_res = ltc_ecc_is_point_at_infinity(S, ltc_key.dp.prime, 183 &inf); 184 } else { 185 ltc_res = ltc_ecc_is_point_at_infinity(C1, ltc_key.dp.prime, 186 &inf); 187 } 188 if (ltc_res != CRYPT_OK || inf) { 189 res = TEE_ERROR_BAD_STATE; 190 goto out; 191 } 192 193 /* Step B3: (x2, y2) = [dB]C1 */ 194 195 x2y2p = ltc_ecc_new_point(); 196 if (!x2y2p) { 197 res = TEE_ERROR_OUT_OF_MEMORY; 198 goto out; 199 } 200 201 ltc_res = ltc_ecc_mulmod(ltc_key.k, C1, x2y2p, ltc_key.dp.A, 202 ltc_key.dp.prime, 1); 203 if (ltc_res != CRYPT_OK) { 204 res = TEE_ERROR_BAD_STATE; 205 goto out; 206 } 207 208 if (mp_unsigned_bin_size(x2y2p->x) > SM2_INT_SIZE_BYTES || 209 mp_unsigned_bin_size(x2y2p->y) > SM2_INT_SIZE_BYTES) { 210 res = TEE_ERROR_BAD_STATE; 211 goto out; 212 } 213 214 mp_to_unsigned_bin2(x2y2p->x, x2y2, SM2_INT_SIZE_BYTES); 215 mp_to_unsigned_bin2(x2y2p->y, x2y2 + SM2_INT_SIZE_BYTES, 216 SM2_INT_SIZE_BYTES); 217 218 /* Step B4: t = KDF(x2 || y2, klen) */ 219 220 /* C = C1 || C2 || C3 */ 221 if (src_len <= C1_len + TEE_SM3_HASH_SIZE) { 222 res = TEE_ERROR_BAD_PARAMETERS; 223 goto out; 224 } 225 226 C2_len = src_len - C1_len - TEE_SM3_HASH_SIZE; 227 228 t = calloc(1, C2_len); 229 if (!t) { 230 res = TEE_ERROR_OUT_OF_MEMORY; 231 goto out; 232 } 233 234 res = sm2_kdf(x2y2, sizeof(x2y2), t, C2_len); 235 if (res) 236 goto out; 237 238 if (is_zero(t, C2_len)) { 239 res = TEE_ERROR_CIPHERTEXT_INVALID; 240 goto out; 241 } 242 243 /* Step B5: get C2 from C and compute Mprime = C2 (+) t */ 244 245 out_len = MIN(*dst_len, C2_len); 246 for (i = 0; i < out_len; i++) 247 dst[i] = src[C1_len + i] ^ t[i]; 248 *dst_len = out_len; 249 if (out_len < C2_len) { 250 eom = calloc(1, C2_len - out_len); 251 if (!eom) { 252 res = TEE_ERROR_OUT_OF_MEMORY; 253 goto out; 254 } 255 for (i = out_len; i < C2_len; i++) 256 eom[i - out_len] = src[C1_len + i] ^ t[i]; 257 } 258 259 /* Step B6: compute u = Hash(x2 || M' || y2) and compare with C3 */ 260 261 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3); 262 if (res) 263 goto out; 264 res = crypto_hash_init(ctx); 265 if (res) 266 goto out; 267 res = crypto_hash_update(ctx, x2y2, SM2_INT_SIZE_BYTES); 268 if (res) 269 goto out; 270 res = crypto_hash_update(ctx, dst, out_len); 271 if (res) 272 goto out; 273 if (out_len < C2_len) { 274 res = crypto_hash_update(ctx, eom, C2_len - out_len); 275 if (res) 276 goto out; 277 } 278 res = crypto_hash_update(ctx, x2y2 + SM2_INT_SIZE_BYTES, 279 SM2_INT_SIZE_BYTES); 280 if (res) 281 goto out; 282 res = crypto_hash_final(ctx, u, sizeof(u)); 283 if (res) 284 goto out; 285 286 if (consttime_memcmp(u, src + C1_len + C2_len, TEE_SM3_HASH_SIZE)) { 287 res = TEE_ERROR_CIPHERTEXT_INVALID; 288 goto out; 289 } 290 out: 291 free(eom); 292 free(t); 293 crypto_hash_free_ctx(ctx); 294 ltc_ecc_del_point(x2y2p); 295 ltc_ecc_del_point(S); 296 ltc_ecc_del_point(C1); 297 mp_clear_multi(h, NULL); 298 ecc_free(<c_key); 299 return res; 300 } 301 302 /* 303 * GM/T 0003.1‒2012 Part 1 Section 4.2.8 304 * Conversion of point @p to a byte string @buf (uncompressed form). 305 */ 306 static TEE_Result sm2_point_to_bytes(uint8_t *buf, size_t *size, 307 const ecc_point *p) 308 { 309 size_t xsize = mp_unsigned_bin_size(p->x); 310 size_t ysize = mp_unsigned_bin_size(p->y); 311 size_t sz = 2 * SM2_INT_SIZE_BYTES + 1; 312 313 if (xsize > SM2_INT_SIZE_BYTES || ysize > SM2_INT_SIZE_BYTES || 314 *size < sz) 315 return TEE_ERROR_BAD_STATE; 316 317 memset(buf, 0, sz); 318 buf[0] = 0x04; /* Uncompressed form indicator */ 319 mp_to_unsigned_bin2(p->x, buf + 1, SM2_INT_SIZE_BYTES); 320 mp_to_unsigned_bin2(p->y, buf + 1 + SM2_INT_SIZE_BYTES, 321 SM2_INT_SIZE_BYTES); 322 323 *size = sz; 324 325 return TEE_SUCCESS; 326 } 327 328 /* 329 * GM/T 0003.1‒2012 Part 4 Section 6.1 330 * Encryption algorithm 331 */ 332 TEE_Result sm2_ltc_pke_encrypt(struct ecc_public_key *key, const uint8_t *src, 333 size_t src_len, uint8_t *dst, size_t *dst_len) 334 { 335 TEE_Result res = TEE_SUCCESS; 336 ecc_key ltc_key = { }; 337 ecc_point *x2y2p = NULL; 338 ecc_point *C1 = NULL; 339 ecc_point *S = NULL; 340 uint8_t x2y2[64] = { }; 341 uint8_t *t = NULL; 342 int ltc_res = 0; 343 void *k = NULL; 344 void *h = NULL; 345 int inf = 0; 346 size_t C1_len = 0; 347 void *ctx = NULL; 348 size_t i = 0; 349 350 ltc_res = mp_init_multi(&k, &h, NULL); 351 if (ltc_res != CRYPT_OK) 352 return TEE_ERROR_OUT_OF_MEMORY; 353 354 res = ecc_populate_ltc_public_key(<c_key, key, TEE_ALG_SM2_PKE, NULL); 355 if (res) 356 goto out; 357 358 /* Step A1: generate random number 1 <= k < n */ 359 360 ltc_res = rand_bn_upto(k, ltc_key.dp.order, NULL, 361 find_prng("prng_crypto")); 362 if (ltc_res != CRYPT_OK) { 363 res = TEE_ERROR_BAD_STATE; 364 goto out; 365 } 366 367 /* Step A2: compute C1 = [k]G */ 368 369 C1 = ltc_ecc_new_point(); 370 if (!C1) { 371 res = TEE_ERROR_OUT_OF_MEMORY; 372 goto out; 373 } 374 375 ltc_res = ltc_ecc_mulmod(k, <c_key.dp.base, C1, ltc_key.dp.A, 376 ltc_key.dp.prime, 1); 377 if (ltc_res != CRYPT_OK) { 378 res = TEE_ERROR_BAD_STATE; 379 goto out; 380 } 381 382 /* Step A3: compute S = [h]PB and check for infinity */ 383 384 if (ltc_key.dp.cofactor != 1) { 385 S = ltc_ecc_new_point(); 386 if (!S) { 387 res = TEE_ERROR_OUT_OF_MEMORY; 388 goto out; 389 } 390 391 ltc_res = mp_set_int(h, ltc_key.dp.cofactor); 392 if (ltc_res != CRYPT_OK) { 393 res = TEE_ERROR_BAD_STATE; 394 goto out; 395 } 396 397 ltc_res = ltc_ecc_mulmod(h, <c_key.pubkey, S, ltc_key.dp.A, 398 ltc_key.dp.prime, 1); 399 if (ltc_res != CRYPT_OK) { 400 res = TEE_ERROR_BAD_STATE; 401 goto out; 402 } 403 404 ltc_res = ltc_ecc_is_point_at_infinity(S, ltc_key.dp.prime, 405 &inf); 406 } else { 407 ltc_res = ltc_ecc_is_point_at_infinity(<c_key.pubkey, 408 ltc_key.dp.prime, &inf); 409 } 410 if (ltc_res != CRYPT_OK) { 411 res = TEE_ERROR_BAD_STATE; 412 goto out; 413 } 414 if (inf) { 415 res = TEE_ERROR_BAD_STATE; 416 goto out; 417 } 418 419 /* Step A4: compute (x2, y2) = [k]PB */ 420 421 x2y2p = ltc_ecc_new_point(); 422 if (!x2y2p) { 423 res = TEE_ERROR_OUT_OF_MEMORY; 424 goto out; 425 } 426 427 ltc_res = ltc_ecc_mulmod(k, <c_key.pubkey, x2y2p, ltc_key.dp.A, 428 ltc_key.dp.prime, 1); 429 if (ltc_res != CRYPT_OK) { 430 res = TEE_ERROR_BAD_STATE; 431 goto out; 432 } 433 434 if (mp_unsigned_bin_size(x2y2p->x) > SM2_INT_SIZE_BYTES || 435 mp_unsigned_bin_size(x2y2p->y) > SM2_INT_SIZE_BYTES) { 436 res = TEE_ERROR_BAD_STATE; 437 goto out; 438 } 439 440 mp_to_unsigned_bin2(x2y2p->x, x2y2, SM2_INT_SIZE_BYTES); 441 mp_to_unsigned_bin2(x2y2p->y, x2y2 + SM2_INT_SIZE_BYTES, 442 SM2_INT_SIZE_BYTES); 443 444 /* Step A5: compute t = KDF(x2 || y2, klen) */ 445 446 t = calloc(1, src_len); 447 if (!t) { 448 res = TEE_ERROR_OUT_OF_MEMORY; 449 goto out; 450 } 451 452 res = sm2_kdf(x2y2, sizeof(x2y2), t, src_len); 453 if (res) 454 goto out; 455 456 if (is_zero(t, src_len)) { 457 res = TEE_ERROR_CIPHERTEXT_INVALID; 458 goto out; 459 } 460 461 /* 462 * Steps A6, A7, A8: 463 * Compute C2 = M (+) t 464 * Compute C3 = Hash(x2 || M || y2) 465 * Output C = C1 || C2 || C3 466 */ 467 468 /* C1 */ 469 C1_len = *dst_len; 470 res = sm2_point_to_bytes(dst, &C1_len, C1); 471 if (res) 472 goto out; 473 474 if (*dst_len < C1_len + src_len + TEE_SM3_HASH_SIZE) { 475 *dst_len = C1_len + src_len + TEE_SM3_HASH_SIZE; 476 res = TEE_ERROR_SHORT_BUFFER; 477 goto out; 478 } 479 480 /* C2 */ 481 for (i = 0; i < src_len; i++) 482 dst[i + C1_len] = src[i] ^ t[i]; 483 484 /* C3 */ 485 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3); 486 if (res) 487 goto out; 488 res = crypto_hash_init(ctx); 489 if (res) 490 goto out; 491 res = crypto_hash_update(ctx, x2y2, SM2_INT_SIZE_BYTES); 492 if (res) 493 goto out; 494 res = crypto_hash_update(ctx, src, src_len); 495 if (res) 496 goto out; 497 res = crypto_hash_update(ctx, x2y2 + SM2_INT_SIZE_BYTES, 498 SM2_INT_SIZE_BYTES); 499 if (res) 500 goto out; 501 res = crypto_hash_final(ctx, dst + C1_len + src_len, TEE_SM3_HASH_SIZE); 502 if (res) 503 goto out; 504 505 *dst_len = C1_len + src_len + TEE_SM3_HASH_SIZE; 506 out: 507 crypto_hash_free_ctx(ctx); 508 free(t); 509 ltc_ecc_del_point(x2y2p); 510 ltc_ecc_del_point(S); 511 ltc_ecc_del_point(C1); 512 ecc_free(<c_key); 513 mp_clear_multi(k, h, NULL); 514 return res; 515 } 516