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