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