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