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