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