1*76c7ba4bSJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2*76c7ba4bSJerome Forissier /* 3*76c7ba4bSJerome Forissier * Copyright (c) 2019 Huawei Technologies Co., Ltd 4*76c7ba4bSJerome Forissier */ 5*76c7ba4bSJerome Forissier 6*76c7ba4bSJerome Forissier #include <crypto/crypto.h> 7*76c7ba4bSJerome Forissier #include <stdlib.h> 8*76c7ba4bSJerome Forissier #include <string.h> 9*76c7ba4bSJerome Forissier #include <tee_api_types.h> 10*76c7ba4bSJerome Forissier #include <util.h> 11*76c7ba4bSJerome Forissier #include <utee_defines.h> 12*76c7ba4bSJerome Forissier 13*76c7ba4bSJerome Forissier #include "acipher_helpers.h" 14*76c7ba4bSJerome Forissier 15*76c7ba4bSJerome Forissier /* 16*76c7ba4bSJerome Forissier * GM/T 0003.1‒2012 Part1 2 Section 6.1 17*76c7ba4bSJerome Forissier */ 18*76c7ba4bSJerome Forissier TEE_Result crypto_acipher_sm2_dsa_sign(uint32_t algo, 19*76c7ba4bSJerome Forissier struct ecc_keypair *key, 20*76c7ba4bSJerome Forissier const uint8_t *msg, size_t msg_len, 21*76c7ba4bSJerome Forissier uint8_t *sig, size_t *sig_len) 22*76c7ba4bSJerome Forissier { 23*76c7ba4bSJerome Forissier TEE_Result res = TEE_SUCCESS; 24*76c7ba4bSJerome Forissier ecc_point *x1y1p = NULL; 25*76c7ba4bSJerome Forissier ecc_key ltc_key = { }; 26*76c7ba4bSJerome Forissier int ltc_res = 0; 27*76c7ba4bSJerome Forissier void *k = NULL; 28*76c7ba4bSJerome Forissier void *e = NULL; 29*76c7ba4bSJerome Forissier void *r = NULL; 30*76c7ba4bSJerome Forissier void *s = NULL; 31*76c7ba4bSJerome Forissier void *tmp = NULL; 32*76c7ba4bSJerome Forissier 33*76c7ba4bSJerome Forissier if (*sig_len < 64) { 34*76c7ba4bSJerome Forissier *sig_len = 64; 35*76c7ba4bSJerome Forissier return TEE_ERROR_SHORT_BUFFER; 36*76c7ba4bSJerome Forissier } 37*76c7ba4bSJerome Forissier 38*76c7ba4bSJerome Forissier ltc_res = mp_init_multi(&k, &e, &r, &s, &tmp, NULL); 39*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) 40*76c7ba4bSJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 41*76c7ba4bSJerome Forissier 42*76c7ba4bSJerome Forissier x1y1p = ltc_ecc_new_point(); 43*76c7ba4bSJerome Forissier if (!x1y1p) { 44*76c7ba4bSJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY; 45*76c7ba4bSJerome Forissier goto out; 46*76c7ba4bSJerome Forissier } 47*76c7ba4bSJerome Forissier 48*76c7ba4bSJerome Forissier res = ecc_populate_ltc_private_key(<c_key, key, algo, NULL); 49*76c7ba4bSJerome Forissier if (res) 50*76c7ba4bSJerome Forissier goto out; 51*76c7ba4bSJerome Forissier 52*76c7ba4bSJerome Forissier /* 53*76c7ba4bSJerome Forissier * Steps A1 and A2 are the generation of the hash value e from user 54*76c7ba4bSJerome Forissier * information (ZA) and the message to be signed (M). There are not done 55*76c7ba4bSJerome Forissier * here since @msg is expected to be the hash value e already. 56*76c7ba4bSJerome Forissier */ 57*76c7ba4bSJerome Forissier 58*76c7ba4bSJerome Forissier /* Step A3: generate random number 1 <= k < n */ 59*76c7ba4bSJerome Forissier A3: 60*76c7ba4bSJerome Forissier ltc_res = rand_bn_upto(k, ltc_key.dp.order, NULL, 61*76c7ba4bSJerome Forissier find_prng("prng_crypto")); 62*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 63*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 64*76c7ba4bSJerome Forissier goto out; 65*76c7ba4bSJerome Forissier } 66*76c7ba4bSJerome Forissier 67*76c7ba4bSJerome Forissier /* Step A4: compute (x1, y1) = [k]G */ 68*76c7ba4bSJerome Forissier 69*76c7ba4bSJerome Forissier ltc_res = ltc_ecc_mulmod(k, <c_key.dp.base, x1y1p, ltc_key.dp.A, 70*76c7ba4bSJerome Forissier ltc_key.dp.prime, 1); 71*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 72*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 73*76c7ba4bSJerome Forissier goto out; 74*76c7ba4bSJerome Forissier } 75*76c7ba4bSJerome Forissier 76*76c7ba4bSJerome Forissier /* Step A5: compute r = (e + x1) mod n */ 77*76c7ba4bSJerome Forissier 78*76c7ba4bSJerome Forissier mp_read_unsigned_bin(e, (unsigned char *)msg, msg_len); 79*76c7ba4bSJerome Forissier ltc_res = mp_addmod(e, x1y1p->x, ltc_key.dp.order, r); 80*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 81*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 82*76c7ba4bSJerome Forissier goto out; 83*76c7ba4bSJerome Forissier } 84*76c7ba4bSJerome Forissier ltc_res = mp_add(r, k, tmp); 85*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 86*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 87*76c7ba4bSJerome Forissier goto out; 88*76c7ba4bSJerome Forissier } 89*76c7ba4bSJerome Forissier if (mp_cmp_d(r, 0) == LTC_MP_EQ || 90*76c7ba4bSJerome Forissier mp_cmp(tmp, ltc_key.dp.order) == LTC_MP_EQ) 91*76c7ba4bSJerome Forissier goto A3; 92*76c7ba4bSJerome Forissier 93*76c7ba4bSJerome Forissier /* Step A6: compute s = ((1 + dA)^-1 * (k - r*dA)) mod n */ 94*76c7ba4bSJerome Forissier 95*76c7ba4bSJerome Forissier ltc_res = mp_add_d(ltc_key.k, 1, s); 96*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 97*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 98*76c7ba4bSJerome Forissier goto out; 99*76c7ba4bSJerome Forissier } 100*76c7ba4bSJerome Forissier ltc_res = mp_invmod(s, ltc_key.dp.order, s); 101*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 102*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 103*76c7ba4bSJerome Forissier goto out; 104*76c7ba4bSJerome Forissier } 105*76c7ba4bSJerome Forissier ltc_res = mp_mul(r, ltc_key.k, tmp); 106*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 107*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 108*76c7ba4bSJerome Forissier goto out; 109*76c7ba4bSJerome Forissier } 110*76c7ba4bSJerome Forissier ltc_res = mp_sub(k, tmp, tmp); 111*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 112*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 113*76c7ba4bSJerome Forissier goto out; 114*76c7ba4bSJerome Forissier } 115*76c7ba4bSJerome Forissier ltc_res = mp_mulmod(s, tmp, ltc_key.dp.order, s); 116*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 117*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 118*76c7ba4bSJerome Forissier goto out; 119*76c7ba4bSJerome Forissier } 120*76c7ba4bSJerome Forissier 121*76c7ba4bSJerome Forissier /* Step A7: convert (r, s) to binary for output */ 122*76c7ba4bSJerome Forissier 123*76c7ba4bSJerome Forissier memset(sig, 0, 64); 124*76c7ba4bSJerome Forissier mp_to_unsigned_bin(r, sig); 125*76c7ba4bSJerome Forissier mp_to_unsigned_bin(s, sig + 32); 126*76c7ba4bSJerome Forissier *sig_len = 64; 127*76c7ba4bSJerome Forissier out: 128*76c7ba4bSJerome Forissier ltc_ecc_del_point(x1y1p); 129*76c7ba4bSJerome Forissier mp_clear_multi(k, e, r, s, tmp, NULL); 130*76c7ba4bSJerome Forissier return res; 131*76c7ba4bSJerome Forissier } 132*76c7ba4bSJerome Forissier 133*76c7ba4bSJerome Forissier /* 134*76c7ba4bSJerome Forissier * GM/T 0003.1‒2012 Part1 2 Section 7.1 135*76c7ba4bSJerome Forissier */ 136*76c7ba4bSJerome Forissier TEE_Result crypto_acipher_sm2_dsa_verify(uint32_t algo, 137*76c7ba4bSJerome Forissier struct ecc_public_key *key, 138*76c7ba4bSJerome Forissier const uint8_t *msg, size_t msg_len, 139*76c7ba4bSJerome Forissier const uint8_t *sig, size_t sig_len) 140*76c7ba4bSJerome Forissier { 141*76c7ba4bSJerome Forissier TEE_Result res = TEE_SUCCESS; 142*76c7ba4bSJerome Forissier ecc_key ltc_key = { }; 143*76c7ba4bSJerome Forissier int ltc_res = 0; 144*76c7ba4bSJerome Forissier void *rprime = NULL; 145*76c7ba4bSJerome Forissier void *sprime = NULL; 146*76c7ba4bSJerome Forissier void *t = NULL; 147*76c7ba4bSJerome Forissier void *mp = NULL; 148*76c7ba4bSJerome Forissier void *mu = NULL; 149*76c7ba4bSJerome Forissier void *ma = NULL; 150*76c7ba4bSJerome Forissier void *eprime = NULL; 151*76c7ba4bSJerome Forissier void *R = NULL; 152*76c7ba4bSJerome Forissier ecc_point *x1y1p = NULL; 153*76c7ba4bSJerome Forissier 154*76c7ba4bSJerome Forissier if (sig_len != 64) 155*76c7ba4bSJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 156*76c7ba4bSJerome Forissier 157*76c7ba4bSJerome Forissier ltc_res = mp_init_multi(&rprime, &sprime, &t, &mu, &ma, &eprime, &R, 158*76c7ba4bSJerome Forissier NULL); 159*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) 160*76c7ba4bSJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 161*76c7ba4bSJerome Forissier 162*76c7ba4bSJerome Forissier mp_read_unsigned_bin(rprime, (unsigned char *)sig, 32); 163*76c7ba4bSJerome Forissier mp_read_unsigned_bin(sprime, (unsigned char *)sig + 32, 32); 164*76c7ba4bSJerome Forissier 165*76c7ba4bSJerome Forissier res = ecc_populate_ltc_public_key(<c_key, key, algo, NULL); 166*76c7ba4bSJerome Forissier if (res) 167*76c7ba4bSJerome Forissier goto out; 168*76c7ba4bSJerome Forissier 169*76c7ba4bSJerome Forissier /* Step B1: verify r' in [1, n - 1] */ 170*76c7ba4bSJerome Forissier 171*76c7ba4bSJerome Forissier if (mp_cmp_d(rprime, 1) == LTC_MP_LT || 172*76c7ba4bSJerome Forissier mp_cmp(rprime, ltc_key.dp.order) != LTC_MP_LT) { 173*76c7ba4bSJerome Forissier res = TEE_ERROR_SIGNATURE_INVALID; 174*76c7ba4bSJerome Forissier goto out; 175*76c7ba4bSJerome Forissier } 176*76c7ba4bSJerome Forissier 177*76c7ba4bSJerome Forissier /* Step B2: verify s' in [1, n - 1] */ 178*76c7ba4bSJerome Forissier 179*76c7ba4bSJerome Forissier if (mp_cmp_d(sprime, 1) == LTC_MP_LT || 180*76c7ba4bSJerome Forissier mp_cmp(sprime, ltc_key.dp.order) != LTC_MP_LT) { 181*76c7ba4bSJerome Forissier res = TEE_ERROR_SIGNATURE_INVALID; 182*76c7ba4bSJerome Forissier goto out; 183*76c7ba4bSJerome Forissier } 184*76c7ba4bSJerome Forissier 185*76c7ba4bSJerome Forissier /* 186*76c7ba4bSJerome Forissier * Steps B3: M'bar = (ZA || M') and B4: e' = Hv(M'bar) are not done here 187*76c7ba4bSJerome Forissier * because @msg is supposed to contain the hash value e' already. 188*76c7ba4bSJerome Forissier */ 189*76c7ba4bSJerome Forissier 190*76c7ba4bSJerome Forissier /* Step B5: t = (r' + s') mod n and check t != 0 */ 191*76c7ba4bSJerome Forissier 192*76c7ba4bSJerome Forissier ltc_res = mp_addmod(rprime, sprime, ltc_key.dp.order, t); 193*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 194*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 195*76c7ba4bSJerome Forissier goto out; 196*76c7ba4bSJerome Forissier } 197*76c7ba4bSJerome Forissier if (mp_cmp_d(t, 0) == LTC_MP_EQ) { 198*76c7ba4bSJerome Forissier res = TEE_ERROR_SIGNATURE_INVALID; 199*76c7ba4bSJerome Forissier goto out; 200*76c7ba4bSJerome Forissier } 201*76c7ba4bSJerome Forissier 202*76c7ba4bSJerome Forissier /* Step B6: (x1', y1') = [s']G + [t]PA */ 203*76c7ba4bSJerome Forissier 204*76c7ba4bSJerome Forissier x1y1p = ltc_ecc_new_point(); 205*76c7ba4bSJerome Forissier if (!x1y1p) { 206*76c7ba4bSJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY; 207*76c7ba4bSJerome Forissier goto out; 208*76c7ba4bSJerome Forissier } 209*76c7ba4bSJerome Forissier ltc_res = mp_montgomery_setup(ltc_key.dp.prime, &mp); 210*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 211*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 212*76c7ba4bSJerome Forissier goto out; 213*76c7ba4bSJerome Forissier } 214*76c7ba4bSJerome Forissier ltc_res = mp_montgomery_normalization(mu, ltc_key.dp.prime); 215*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 216*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 217*76c7ba4bSJerome Forissier goto out; 218*76c7ba4bSJerome Forissier } 219*76c7ba4bSJerome Forissier ltc_res = mp_mulmod(ltc_key.dp.A, mu, ltc_key.dp.prime, ma); 220*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 221*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 222*76c7ba4bSJerome Forissier goto out; 223*76c7ba4bSJerome Forissier } 224*76c7ba4bSJerome Forissier ltc_res = ltc_ecc_mul2add(<c_key.dp.base, sprime, <c_key.pubkey, t, 225*76c7ba4bSJerome Forissier x1y1p, ma, ltc_key.dp.prime); 226*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 227*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 228*76c7ba4bSJerome Forissier goto out; 229*76c7ba4bSJerome Forissier } 230*76c7ba4bSJerome Forissier 231*76c7ba4bSJerome Forissier /* Step B7: compute R = (e' + x1') mod n and verify R == r' */ 232*76c7ba4bSJerome Forissier 233*76c7ba4bSJerome Forissier mp_read_unsigned_bin(eprime, (unsigned char *)msg, msg_len); 234*76c7ba4bSJerome Forissier ltc_res = mp_addmod(eprime, x1y1p->x, ltc_key.dp.order, R); 235*76c7ba4bSJerome Forissier if (ltc_res != CRYPT_OK) { 236*76c7ba4bSJerome Forissier res = TEE_ERROR_BAD_STATE; 237*76c7ba4bSJerome Forissier goto out; 238*76c7ba4bSJerome Forissier } 239*76c7ba4bSJerome Forissier if (mp_cmp(R, rprime) != LTC_MP_EQ) 240*76c7ba4bSJerome Forissier res = TEE_ERROR_SIGNATURE_INVALID; 241*76c7ba4bSJerome Forissier out: 242*76c7ba4bSJerome Forissier mp_montgomery_free(mp); 243*76c7ba4bSJerome Forissier ltc_ecc_del_point(x1y1p); 244*76c7ba4bSJerome Forissier mp_clear_multi(rprime, sprime, t, mu, ma, eprime, R, NULL); 245*76c7ba4bSJerome Forissier return res; 246*76c7ba4bSJerome Forissier } 247