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