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