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