1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019-2021 Huawei Technologies Co., Ltd 4 */ 5 6 #include <compiler.h> 7 #include <crypto/crypto.h> 8 #include <mbedtls/bignum.h> 9 #include <mbedtls/ecp.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <tee_api_types.h> 13 #include <util.h> 14 #include <utee_defines.h> 15 16 #include "mbed_helpers.h" 17 #include "sm2-dsa.h" 18 19 /* SM2 uses 256 bit unsigned integers in big endian format */ 20 #define SM2_INT_SIZE_BYTES 32 21 22 /* 23 * GM/T 0003.1‒2012 Part1 2 Section 6.1 24 */ 25 TEE_Result sm2_mbedtls_dsa_sign(uint32_t algo __unused, struct ecc_keypair *key, 26 const uint8_t *msg, size_t msg_len, 27 uint8_t *sig, size_t *sig_len) 28 { 29 TEE_Result res = TEE_SUCCESS; 30 mbedtls_ecp_group grp = { }; 31 mbedtls_ecp_point x1y1p = { }; 32 int mres = 0; 33 mbedtls_mpi k = { }; 34 mbedtls_mpi e = { }; 35 mbedtls_mpi r = { }; 36 mbedtls_mpi s = { }; 37 mbedtls_mpi tmp = { }; 38 39 if (*sig_len < 2 * SM2_INT_SIZE_BYTES) { 40 *sig_len = 64; 41 return TEE_ERROR_SHORT_BUFFER; 42 } 43 44 mbedtls_mpi_init(&k); 45 mbedtls_mpi_init(&e); 46 mbedtls_mpi_init(&r); 47 mbedtls_mpi_init(&s); 48 mbedtls_mpi_init(&tmp); 49 50 mbedtls_ecp_point_init(&x1y1p); 51 52 mbedtls_ecp_group_init(&grp); 53 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2); 54 if (mres) { 55 res = TEE_ERROR_GENERIC; 56 goto out; 57 } 58 59 /* 60 * Steps A1 and A2 are the generation of the hash value e from user 61 * information (ZA) and the message to be signed (M). There are not done 62 * here since @msg is expected to be the hash value e already. 63 */ 64 65 /* Step A3: generate random number 1 <= k < n */ 66 do { 67 res = mbed_gen_random_upto(&k, &grp.N); 68 if (res) 69 goto out; 70 71 res = TEE_ERROR_BAD_STATE; 72 73 /* Step A4: compute (x1, y1) = [k]G */ 74 75 mres = mbedtls_ecp_mul(&grp, &x1y1p, &k, &grp.G, mbd_rand, 76 NULL); 77 if (mres) 78 goto out; 79 80 /* Step A5: compute r = (e + x1) mod n */ 81 82 mbedtls_mpi_read_binary(&e, (unsigned char *)msg, msg_len); 83 mres = mbedtls_mpi_add_mpi(&r, &e, &x1y1p.X); 84 if (mres) 85 goto out; 86 mres = mbedtls_mpi_mod_mpi(&r, &r, &grp.N); 87 if (mres) 88 goto out; 89 90 /* Step A5 (continued): return to A3 if r = 0 or r + k = n */ 91 92 mres = mbedtls_mpi_add_mpi(&tmp, &r, &k); 93 if (mres) 94 goto out; 95 } while (!mbedtls_mpi_cmp_int(&r, 0) || 96 !mbedtls_mpi_cmp_mpi(&tmp, &grp.N)); 97 98 /* Step A6: compute s = ((1 + dA)^-1 * (k - r*dA)) mod n */ 99 100 mres = mbedtls_mpi_add_int(&s, (mbedtls_mpi *)key->d, 1); 101 if (mres) 102 goto out; 103 mres = mbedtls_mpi_inv_mod(&s, &s, &grp.N); 104 if (mres) 105 goto out; 106 mres = mbedtls_mpi_mul_mpi(&tmp, &r, (mbedtls_mpi *)key->d); 107 if (mres) 108 goto out; 109 mres = mbedtls_mpi_mod_mpi(&tmp, &tmp, &grp.N); 110 if (mres) 111 goto out; 112 mres = mbedtls_mpi_sub_mpi(&tmp, &k, &tmp); 113 if (mres) 114 goto out; 115 mres = mbedtls_mpi_mul_mpi(&s, &s, &tmp); 116 if (mres) 117 goto out; 118 mres = mbedtls_mpi_mod_mpi(&s, &s, &grp.N); 119 if (mres) 120 goto out; 121 122 /* Step A7: convert (r, s) to binary for output */ 123 124 *sig_len = 2 * SM2_INT_SIZE_BYTES; 125 memset(sig, 0, *sig_len); 126 mres = mbedtls_mpi_write_binary(&r, sig, SM2_INT_SIZE_BYTES); 127 if (mres) 128 goto out; 129 mres = mbedtls_mpi_write_binary(&s, sig + SM2_INT_SIZE_BYTES, 130 SM2_INT_SIZE_BYTES); 131 if (mres) 132 goto out; 133 134 res = TEE_SUCCESS; 135 out: 136 mbedtls_ecp_point_free(&x1y1p); 137 mbedtls_mpi_free(&k); 138 mbedtls_mpi_free(&e); 139 mbedtls_mpi_free(&r); 140 mbedtls_mpi_free(&s); 141 mbedtls_mpi_free(&tmp); 142 mbedtls_ecp_group_free(&grp); 143 return res; 144 } 145 146 /* 147 * GM/T 0003.1‒2012 Part1 2 Section 7.1 148 */ 149 TEE_Result sm2_mbedtls_dsa_verify(uint32_t algo __unused, 150 struct ecc_public_key *key, 151 const uint8_t *msg, size_t msg_len, 152 const uint8_t *sig, size_t sig_len) 153 { 154 TEE_Result res = TEE_ERROR_BAD_STATE; 155 mbedtls_ecp_group grp = { }; 156 mbedtls_mpi rprime = { }; 157 mbedtls_mpi sprime = { }; 158 mbedtls_mpi t = { }; 159 mbedtls_mpi eprime = { }; 160 mbedtls_mpi R = { }; 161 mbedtls_ecp_point x1y1p = { }; 162 mbedtls_ecp_point PA = { }; 163 int mres = 0; 164 165 if (sig_len != 64) 166 return TEE_ERROR_BAD_PARAMETERS; 167 168 mbedtls_mpi_init(&rprime); 169 mbedtls_mpi_init(&sprime); 170 mbedtls_mpi_init(&t); 171 mbedtls_mpi_init(&eprime); 172 mbedtls_mpi_init(&R); 173 174 mbedtls_ecp_point_init(&x1y1p); 175 mbedtls_ecp_point_init(&PA); 176 177 mbedtls_ecp_group_init(&grp); 178 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2); 179 if (mres) { 180 res = TEE_ERROR_GENERIC; 181 goto out; 182 } 183 184 mres = mbedtls_mpi_read_binary(&rprime, sig, 32); 185 if (mres) 186 goto out; 187 mres = mbedtls_mpi_read_binary(&sprime, sig + 32, 32); 188 if (mres) 189 goto out; 190 191 /* Step B1: verify r' in [1, n - 1] */ 192 193 if (mbedtls_mpi_cmp_int(&rprime, 1) < 0 || 194 mbedtls_mpi_cmp_mpi(&rprime, &grp.N) >= 0) { 195 res = TEE_ERROR_SIGNATURE_INVALID; 196 goto out; 197 } 198 199 /* Step B2: verify s' in [1, n - 1] */ 200 201 if (mbedtls_mpi_cmp_int(&sprime, 1) < 0 || 202 mbedtls_mpi_cmp_mpi(&sprime, &grp.N) >= 0) { 203 res = TEE_ERROR_SIGNATURE_INVALID; 204 goto out; 205 } 206 207 /* 208 * Steps B3: M'bar = (ZA || M') and B4: e' = Hv(M'bar) are not done here 209 * because @msg is supposed to contain the hash value e' already. 210 */ 211 212 /* Step B5: t = (r' + s') mod n and check t != 0 */ 213 214 mres = mbedtls_mpi_add_mpi(&t, &rprime, &sprime); 215 if (mres) 216 goto out; 217 mres = mbedtls_mpi_mod_mpi(&t, &t, &grp.N); 218 if (mres) 219 goto out; 220 if (!mbedtls_mpi_cmp_int(&t, 0)) { 221 res = TEE_ERROR_SIGNATURE_INVALID; 222 goto out; 223 } 224 225 /* Step B6: (x1', y1') = [s']G + [t]PA */ 226 227 mres = mbedtls_mpi_copy(&PA.X, (mbedtls_mpi *)key->x); 228 if (mres) 229 goto out; 230 mres = mbedtls_mpi_copy(&PA.Y, (mbedtls_mpi *)key->y); 231 if (mres) 232 goto out; 233 mres = mbedtls_mpi_lset(&PA.Z, 1); 234 if (mres) 235 goto out; 236 237 mres = mbedtls_ecp_muladd(&grp, &x1y1p, &sprime, &grp.G, &t, &PA); 238 if (mres) 239 goto out; 240 241 /* Step B7: compute R = (e' + x1') mod n and verify R == r' */ 242 243 mres = mbedtls_mpi_read_binary(&eprime, msg, msg_len); 244 if (mres) 245 goto out; 246 mres = mbedtls_mpi_add_mpi(&R, &eprime, &x1y1p.X); 247 if (mres) 248 goto out; 249 mres = mbedtls_mpi_mod_mpi(&R, &R, &grp.N); 250 if (mres) 251 goto out; 252 if (mbedtls_mpi_cmp_mpi(&R, &rprime)) { 253 res = TEE_ERROR_SIGNATURE_INVALID; 254 goto out; 255 } 256 257 res = TEE_SUCCESS; 258 out: 259 mbedtls_ecp_point_free(&x1y1p); 260 mbedtls_ecp_point_free(&PA); 261 mbedtls_mpi_free(&rprime); 262 mbedtls_mpi_free(&sprime); 263 mbedtls_mpi_free(&t); 264 mbedtls_mpi_free(&eprime); 265 mbedtls_mpi_free(&R); 266 mbedtls_ecp_group_free(&grp); 267 return res; 268 } 269