1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2020-21 Huawei Technologies Co., Ltd 4 */ 5 6 #include <crypto/crypto.h> 7 #include <crypto/sm2-kdf.h> 8 #include <mbedtls/bignum.h> 9 #include <mbedtls/ecp.h> 10 #include <string_ext.h> 11 #include <tee_api_types.h> 12 #include <utee_defines.h> 13 14 #include "mbed_helpers.h" 15 16 /* SM2 uses 256 bit unsigned integers in big endian format */ 17 #define SM2_INT_SIZE_BYTES 32 18 19 /* The public x and y values extracted from a public or private ECC key */ 20 struct key_xy { 21 mbedtls_mpi *x; 22 mbedtls_mpi *y; 23 }; 24 25 /* 26 * Compute a hash of a user's identity and public key 27 * For user A: ZA = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA) 28 */ 29 static TEE_Result sm2_kep_compute_Z(const mbedtls_ecp_group *grp, uint8_t *Z, 30 size_t Zlen, const uint8_t *id, 31 size_t idlen, struct key_xy *key) 32 { 33 TEE_Result res = TEE_ERROR_GENERIC; 34 uint8_t ENTLEN[2] = { }; 35 uint8_t buf[SM2_INT_SIZE_BYTES] = { }; 36 void *ctx = NULL; 37 int mres = 0; 38 39 if (Zlen < TEE_SM3_HASH_SIZE) 40 return TEE_ERROR_SHORT_BUFFER; 41 42 /* 43 * ENTLEN is the length in bits if the user's distinguished identifier 44 * encoded over 16 bits in big endian format. 45 */ 46 ENTLEN[0] = (idlen * 8) >> 8; 47 ENTLEN[1] = idlen * 8; 48 49 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3); 50 if (res) 51 goto out; 52 53 res = crypto_hash_init(ctx); 54 if (res) 55 goto out; 56 57 res = crypto_hash_update(ctx, ENTLEN, sizeof(ENTLEN)); 58 if (res) 59 goto out; 60 61 res = crypto_hash_update(ctx, id, idlen); 62 if (res) 63 goto out; 64 65 mres = mbedtls_mpi_write_binary(&grp->A, buf, SM2_INT_SIZE_BYTES); 66 if (mres) { 67 res = TEE_ERROR_GENERIC; 68 goto out; 69 } 70 res = crypto_hash_update(ctx, buf, sizeof(buf)); 71 if (res) 72 goto out; 73 74 mres = mbedtls_mpi_write_binary(&grp->B, buf, SM2_INT_SIZE_BYTES); 75 if (mres) { 76 res = TEE_ERROR_GENERIC; 77 goto out; 78 } 79 res = crypto_hash_update(ctx, buf, sizeof(buf)); 80 if (res) 81 goto out; 82 83 mres = mbedtls_mpi_write_binary(&grp->G.X, buf, SM2_INT_SIZE_BYTES); 84 if (mres) { 85 res = TEE_ERROR_GENERIC; 86 goto out; 87 } 88 res = crypto_hash_update(ctx, buf, sizeof(buf)); 89 if (res) 90 goto out; 91 92 mres = mbedtls_mpi_write_binary(&grp->G.Y, buf, SM2_INT_SIZE_BYTES); 93 if (mres) { 94 res = TEE_ERROR_GENERIC; 95 goto out; 96 } 97 res = crypto_hash_update(ctx, buf, sizeof(buf)); 98 if (res) 99 goto out; 100 101 mres = mbedtls_mpi_write_binary(key->x, buf, SM2_INT_SIZE_BYTES); 102 if (mres) { 103 res = TEE_ERROR_GENERIC; 104 goto out; 105 } 106 res = crypto_hash_update(ctx, buf, sizeof(buf)); 107 if (res) 108 goto out; 109 110 mres = mbedtls_mpi_write_binary(key->y, buf, SM2_INT_SIZE_BYTES); 111 if (mres) { 112 res = TEE_ERROR_GENERIC; 113 goto out; 114 } 115 res = crypto_hash_update(ctx, buf, sizeof(buf)); 116 if (res) 117 goto out; 118 119 res = crypto_hash_final(ctx, Z, TEE_SM3_HASH_SIZE); 120 out: 121 crypto_hash_free_ctx(ctx); 122 return res; 123 } 124 125 /* 126 * Compute a verification value, to be checked against the value sent by the 127 * peer. 128 * On the initiator's side: 129 * S1 = SM3(0x02 || yU || SM3(xU || ZA || ZB || x1 || y1 || x2 || y2)) 130 * On the responder's side: 131 * S2 = SM3(0x03 || yV || SM3(xV || ZA || ZB || x1 || y1 || x2 || y2)) 132 */ 133 static TEE_Result sm2_kep_compute_S(uint8_t *S, size_t S_len, uint8_t flag, 134 mbedtls_ecp_point *UV, const uint8_t *ZAZB, 135 size_t ZAZB_len, 136 struct key_xy *initiator_eph_key, 137 struct key_xy *responder_eph_key) 138 { 139 uint8_t hash[TEE_SM3_HASH_SIZE] = { }; 140 TEE_Result res = TEE_ERROR_GENERIC; 141 uint8_t buf[SM2_INT_SIZE_BYTES]; 142 void *ctx = NULL; 143 int mres = 0; 144 145 if (S_len < TEE_SM3_HASH_SIZE) 146 return TEE_ERROR_SHORT_BUFFER; 147 148 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3); 149 if (res) 150 goto out; 151 152 /* Compute the inner hash */ 153 154 res = crypto_hash_init(ctx); 155 if (res) 156 goto out; 157 158 /* xU or xV */ 159 mres = mbedtls_mpi_write_binary(&UV->X, buf, SM2_INT_SIZE_BYTES); 160 if (mres) { 161 res = TEE_ERROR_GENERIC; 162 goto out; 163 } 164 res = crypto_hash_update(ctx, buf, sizeof(buf)); 165 if (res) 166 goto out; 167 168 /* ZA || ZB */ 169 res = crypto_hash_update(ctx, ZAZB, ZAZB_len); 170 if (res) 171 goto out; 172 173 /* x1 */ 174 mres = mbedtls_mpi_write_binary(initiator_eph_key->x, buf, 175 SM2_INT_SIZE_BYTES); 176 if (mres) { 177 res = TEE_ERROR_GENERIC; 178 goto out; 179 } 180 res = crypto_hash_update(ctx, buf, sizeof(buf)); 181 if (res) 182 goto out; 183 184 /* y1 */ 185 mres = mbedtls_mpi_write_binary(initiator_eph_key->y, buf, 186 SM2_INT_SIZE_BYTES); 187 if (mres) { 188 res = TEE_ERROR_GENERIC; 189 goto out; 190 } 191 res = crypto_hash_update(ctx, buf, sizeof(buf)); 192 if (res) 193 goto out; 194 195 /* x2 */ 196 mres = mbedtls_mpi_write_binary(responder_eph_key->x, buf, 197 SM2_INT_SIZE_BYTES); 198 if (mres) { 199 res = TEE_ERROR_GENERIC; 200 goto out; 201 } 202 res = crypto_hash_update(ctx, buf, sizeof(buf)); 203 if (res) 204 goto out; 205 206 /* y2 */ 207 mres = mbedtls_mpi_write_binary(responder_eph_key->y, buf, 208 SM2_INT_SIZE_BYTES); 209 if (mres) { 210 res = TEE_ERROR_GENERIC; 211 goto out; 212 } 213 res = crypto_hash_update(ctx, buf, sizeof(buf)); 214 if (res) 215 goto out; 216 217 res = crypto_hash_final(ctx, hash, sizeof(hash)); 218 if (res) 219 goto out; 220 221 /* Now compute S */ 222 223 res = crypto_hash_init(ctx); 224 if (res) 225 goto out; 226 227 /* 0x02 or 0x03 */ 228 res = crypto_hash_update(ctx, &flag, sizeof(flag)); 229 if (res) 230 goto out; 231 232 /* yU or yV */ 233 mres = mbedtls_mpi_write_binary(&UV->Y, buf, SM2_INT_SIZE_BYTES); 234 if (mres) { 235 res = TEE_ERROR_GENERIC; 236 goto out; 237 } 238 res = crypto_hash_update(ctx, buf, sizeof(buf)); 239 if (res) 240 goto out; 241 242 /* Inner SM3(...) */ 243 res = crypto_hash_update(ctx, hash, sizeof(hash)); 244 if (res) 245 goto out; 246 247 res = crypto_hash_final(ctx, S, TEE_SM3_HASH_SIZE); 248 249 out: 250 crypto_hash_free_ctx(ctx); 251 return res; 252 253 } 254 255 static void extract_xy_from_keypair(struct key_xy *xy, 256 const struct ecc_keypair *pair) 257 { 258 xy->x = (mbedtls_mpi *)pair->x; 259 xy->y = (mbedtls_mpi *)pair->y; 260 /* Other fields are not used */ 261 } 262 263 static void extract_xy_from_public_key(struct key_xy *xy, 264 const struct ecc_public_key *from) 265 { 266 xy->x = (mbedtls_mpi *)from->x; 267 xy->y = (mbedtls_mpi *)from->y; 268 } 269 270 /* 271 * GM/T 0003.1‒2012 Part 3 Section 6.1 272 * Key exchange protocol 273 */ 274 TEE_Result crypto_acipher_sm2_kep_derive(struct ecc_keypair *my_key, 275 struct ecc_keypair *my_eph_key, 276 struct ecc_public_key *peer_key, 277 struct ecc_public_key *peer_eph_key, 278 struct sm2_kep_parms *p) 279 { 280 /* 281 * Variable names and documented steps reflect the initator side (user A 282 * in the spec), but the other side is quite similar hence only one 283 * function. 284 */ 285 uint8_t xUyUZAZB[2 * SM2_INT_SIZE_BYTES + 2 * TEE_SM3_HASH_SIZE] = { }; 286 struct key_xy initiator_eph_key = { }; 287 struct key_xy responder_eph_key = { }; 288 struct key_xy initiator_key = { }; 289 struct key_xy responder_key = { }; 290 TEE_Result res = TEE_ERROR_BAD_STATE; 291 uint8_t tmp[SM2_INT_SIZE_BYTES] = { }; 292 mbedtls_ecp_group grp = { }; 293 mbedtls_ecp_point PB = { }; 294 mbedtls_ecp_point RB = { }; 295 mbedtls_ecp_point U = { }; 296 mbedtls_mpi x1bar = { }; 297 mbedtls_mpi x2bar = { }; 298 mbedtls_mpi tA = { }; 299 mbedtls_mpi h = { }; 300 mbedtls_mpi htA = { }; 301 mbedtls_mpi one = { }; 302 int mres = 0; 303 304 if (p->is_initiator) { 305 extract_xy_from_keypair(&initiator_eph_key, my_eph_key); 306 extract_xy_from_public_key(&responder_eph_key, peer_eph_key); 307 extract_xy_from_keypair(&initiator_key, my_key); 308 extract_xy_from_public_key(&responder_key, peer_key); 309 } else { 310 extract_xy_from_public_key(&initiator_eph_key, peer_eph_key); 311 extract_xy_from_keypair(&responder_eph_key, my_eph_key); 312 extract_xy_from_public_key(&initiator_key, peer_key); 313 extract_xy_from_keypair(&responder_key, my_key); 314 } 315 316 mbedtls_mpi_init(&x1bar); 317 mbedtls_mpi_init(&x2bar); 318 mbedtls_mpi_init(&tA); 319 mbedtls_mpi_init(&h); 320 mbedtls_mpi_init(&htA); 321 mbedtls_mpi_init(&one); 322 323 mbedtls_ecp_point_init(&PB); 324 mbedtls_ecp_point_init(&RB); 325 mbedtls_ecp_point_init(&U); 326 327 mbedtls_ecp_group_init(&grp); 328 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2); 329 if (mres) 330 goto out; 331 332 /* 333 * Steps A1-A3 are supposedly done already (generate ephemeral key, send 334 * it to peer). 335 * Step A4: (x1, y1) = RA; x1bar = 2^w + (x1 & (2^w - 1)) 336 */ 337 338 mres = mbedtls_mpi_write_binary((mbedtls_mpi *)my_eph_key->x, tmp, 339 SM2_INT_SIZE_BYTES); 340 if (mres) 341 goto out; 342 tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80; 343 mres = mbedtls_mpi_read_binary(&x1bar, tmp + SM2_INT_SIZE_BYTES / 2, 344 SM2_INT_SIZE_BYTES / 2); 345 if (mres) 346 goto out; 347 348 /* Step A5: tA = (dA + x1bar * rA) mod n */ 349 350 mres = mbedtls_mpi_mul_mpi(&tA, &x1bar, (mbedtls_mpi *)my_eph_key->d); 351 if (mres) 352 goto out; 353 mres = mbedtls_mpi_mod_mpi(&tA, &tA, &grp.N); 354 if (mres) 355 goto out; 356 mres = mbedtls_mpi_add_mpi(&tA, &tA, (mbedtls_mpi *)my_key->d); 357 if (mres) 358 goto out; 359 mres = mbedtls_mpi_mod_mpi(&tA, &tA, &grp.N); 360 if (mres) 361 goto out; 362 363 /* Step A6: verify whether RB verifies the curve equation */ 364 365 mbedtls_mpi_copy(&RB.X, (mbedtls_mpi *)peer_eph_key->x); 366 mbedtls_mpi_copy(&RB.Y, (mbedtls_mpi *)peer_eph_key->y); 367 mbedtls_mpi_lset(&RB.Z, 1); 368 mres = mbedtls_ecp_check_pubkey(&grp, &RB); 369 if (mres) 370 goto out; 371 372 /* Step A6 (continued): (x2, y2) = RB; x2bar = 2^w + (x2 & (2^w - 1)) */ 373 374 mres = mbedtls_mpi_write_binary((mbedtls_mpi *)peer_eph_key->x, tmp, 375 SM2_INT_SIZE_BYTES); 376 if (mres) 377 goto out; 378 tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80; 379 mres = mbedtls_mpi_read_binary(&x2bar, tmp + SM2_INT_SIZE_BYTES / 2, 380 SM2_INT_SIZE_BYTES / 2); 381 if (mres) 382 goto out; 383 384 /* Step A7: compute U = [h.tA](PB + [x2bar]RB) and check for infinity */ 385 386 mres = mbedtls_mpi_copy(&PB.X, (mbedtls_mpi *)peer_key->x); 387 if (mres) 388 goto out; 389 mres = mbedtls_mpi_copy(&PB.Y, (mbedtls_mpi *)peer_key->y); 390 if (mres) 391 goto out; 392 mres = mbedtls_mpi_lset(&PB.Z, 1); 393 if (mres) 394 goto out; 395 mres = mbedtls_mpi_lset(&one, 1); 396 if (mres) 397 goto out; 398 399 mres = mbedtls_ecp_muladd(&grp, &U, &one, &PB, &x2bar, &RB); 400 if (mres) 401 goto out; 402 403 /* Note: the cofactor for SM2 is 1 so [h.tA] == tA */ 404 mres = mbedtls_ecp_mul(&grp, &U, &tA, &U, mbd_rand, NULL); 405 if (mres) 406 goto out; 407 408 /* 409 * "Point is zero" is same as "point is at infinity". Returns 1 if 410 * point is zero, < 0 on error and 0 if point is non-zero. 411 */ 412 mres = mbedtls_ecp_is_zero(&U); 413 if (mres) 414 goto out; 415 416 /* Step A8: compute KA = KDF(xU || yU || ZA || ZB, klen) */ 417 418 /* xU */ 419 mres = mbedtls_mpi_write_binary(&U.X, xUyUZAZB, SM2_INT_SIZE_BYTES); 420 if (mres) 421 goto out; 422 423 /* yU */ 424 mres = mbedtls_mpi_write_binary(&U.Y, xUyUZAZB + SM2_INT_SIZE_BYTES, 425 SM2_INT_SIZE_BYTES); 426 if (mres) 427 goto out; 428 429 /* ZA */ 430 res = sm2_kep_compute_Z(&grp, xUyUZAZB + 2 * SM2_INT_SIZE_BYTES, 431 TEE_SM3_HASH_SIZE, p->initiator_id, 432 p->initiator_id_len, &initiator_key); 433 if (res) 434 goto out; 435 436 /* ZB */ 437 res = sm2_kep_compute_Z(&grp, xUyUZAZB + 2 * SM2_INT_SIZE_BYTES + 438 TEE_SM3_HASH_SIZE, 439 TEE_SM3_HASH_SIZE, p->responder_id, 440 p->responder_id_len, &responder_key); 441 if (res) 442 goto out; 443 444 res = sm2_kdf(xUyUZAZB, sizeof(xUyUZAZB), p->out, p->out_len); 445 if (res) 446 goto out; 447 448 /* Step A9: compute S1 and check S1 == SB */ 449 450 if (p->conf_in) { 451 uint8_t S1[TEE_SM3_HASH_SIZE] = { }; 452 uint8_t flag = p->is_initiator ? 0x02 : 0x03; 453 454 if (p->conf_in_len < TEE_SM3_HASH_SIZE) { 455 res = TEE_ERROR_BAD_PARAMETERS; 456 goto out; 457 } 458 res = sm2_kep_compute_S(S1, sizeof(S1), flag, &U, 459 xUyUZAZB + 2 * SM2_INT_SIZE_BYTES, 460 2 * SM2_INT_SIZE_BYTES, 461 &initiator_eph_key, &responder_eph_key); 462 if (res) 463 goto out; 464 465 if (consttime_memcmp(S1, p->conf_in, sizeof(S1))) { 466 /* Verification failed */ 467 res = TEE_ERROR_BAD_STATE; 468 goto out; 469 } 470 } 471 472 /* Step A10: compute SA */ 473 474 if (p->conf_out) { 475 uint8_t flag = p->is_initiator ? 0x03 : 0x02; 476 477 if (p->conf_out_len < TEE_SM3_HASH_SIZE) { 478 res = TEE_ERROR_BAD_PARAMETERS; 479 goto out; 480 } 481 482 res = sm2_kep_compute_S(p->conf_out, TEE_SM3_HASH_SIZE, flag, 483 &U, xUyUZAZB + 2 * SM2_INT_SIZE_BYTES, 484 2 * SM2_INT_SIZE_BYTES, 485 &initiator_eph_key, &responder_eph_key); 486 } 487 out: 488 mbedtls_mpi_free(&x1bar); 489 mbedtls_mpi_free(&x2bar); 490 mbedtls_mpi_free(&tA); 491 mbedtls_mpi_free(&h); 492 mbedtls_mpi_free(&htA); 493 mbedtls_mpi_free(&one); 494 mbedtls_ecp_point_free(&PB); 495 mbedtls_ecp_point_free(&RB); 496 mbedtls_ecp_point_free(&U); 497 mbedtls_ecp_group_free(&grp); 498 return res; 499 } 500