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 return res; 143 } 144 145 /* 146 * GM/T 0003.1‒2012 Part1 2 Section 7.1 147 */ 148 TEE_Result sm2_mbedtls_dsa_verify(uint32_t algo __unused, 149 struct ecc_public_key *key, 150 const uint8_t *msg, size_t msg_len, 151 const uint8_t *sig, size_t sig_len) 152 { 153 TEE_Result res = TEE_ERROR_BAD_STATE; 154 mbedtls_ecp_group grp = { }; 155 mbedtls_mpi rprime = { }; 156 mbedtls_mpi sprime = { }; 157 mbedtls_mpi t = { }; 158 mbedtls_mpi eprime = { }; 159 mbedtls_mpi R = { }; 160 mbedtls_ecp_point x1y1p = { }; 161 mbedtls_ecp_point PA = { }; 162 int mres = 0; 163 164 if (sig_len != 64) 165 return TEE_ERROR_BAD_PARAMETERS; 166 167 mbedtls_mpi_init(&rprime); 168 mbedtls_mpi_init(&sprime); 169 mbedtls_mpi_init(&t); 170 mbedtls_mpi_init(&eprime); 171 mbedtls_mpi_init(&R); 172 173 mbedtls_ecp_point_init(&x1y1p); 174 mbedtls_ecp_point_init(&PA); 175 176 mbedtls_ecp_group_init(&grp); 177 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2); 178 if (mres) { 179 res = TEE_ERROR_GENERIC; 180 goto out; 181 } 182 183 mres = mbedtls_mpi_read_binary(&rprime, sig, 32); 184 if (mres) 185 goto out; 186 mres = mbedtls_mpi_read_binary(&sprime, sig + 32, 32); 187 if (mres) 188 goto out; 189 190 /* Step B1: verify r' in [1, n - 1] */ 191 192 if (mbedtls_mpi_cmp_int(&rprime, 1) < 0 || 193 mbedtls_mpi_cmp_mpi(&rprime, &grp.N) >= 0) { 194 res = TEE_ERROR_SIGNATURE_INVALID; 195 goto out; 196 } 197 198 /* Step B2: verify s' in [1, n - 1] */ 199 200 if (mbedtls_mpi_cmp_int(&sprime, 1) < 0 || 201 mbedtls_mpi_cmp_mpi(&sprime, &grp.N) >= 0) { 202 res = TEE_ERROR_SIGNATURE_INVALID; 203 goto out; 204 } 205 206 /* 207 * Steps B3: M'bar = (ZA || M') and B4: e' = Hv(M'bar) are not done here 208 * because @msg is supposed to contain the hash value e' already. 209 */ 210 211 /* Step B5: t = (r' + s') mod n and check t != 0 */ 212 213 mres = mbedtls_mpi_add_mpi(&t, &rprime, &sprime); 214 if (mres) 215 goto out; 216 mres = mbedtls_mpi_mod_mpi(&t, &t, &grp.N); 217 if (mres) 218 goto out; 219 if (!mbedtls_mpi_cmp_int(&t, 0)) { 220 res = TEE_ERROR_SIGNATURE_INVALID; 221 goto out; 222 } 223 224 /* Step B6: (x1', y1') = [s']G + [t]PA */ 225 226 mres = mbedtls_mpi_copy(&PA.X, (mbedtls_mpi *)key->x); 227 if (mres) 228 goto out; 229 mres = mbedtls_mpi_copy(&PA.Y, (mbedtls_mpi *)key->y); 230 if (mres) 231 goto out; 232 mres = mbedtls_mpi_lset(&PA.Z, 1); 233 if (mres) 234 goto out; 235 236 mres = mbedtls_ecp_muladd(&grp, &x1y1p, &sprime, &grp.G, &t, &PA); 237 if (mres) 238 goto out; 239 240 /* Step B7: compute R = (e' + x1') mod n and verify R == r' */ 241 242 mres = mbedtls_mpi_read_binary(&eprime, msg, msg_len); 243 if (mres) 244 goto out; 245 mres = mbedtls_mpi_add_mpi(&R, &eprime, &x1y1p.X); 246 if (mres) 247 goto out; 248 mres = mbedtls_mpi_mod_mpi(&R, &R, &grp.N); 249 if (mres) 250 goto out; 251 if (mbedtls_mpi_cmp_mpi(&R, &rprime)) { 252 res = TEE_ERROR_SIGNATURE_INVALID; 253 goto out; 254 } 255 256 res = TEE_SUCCESS; 257 out: 258 mbedtls_ecp_point_free(&x1y1p); 259 mbedtls_ecp_point_free(&PA); 260 mbedtls_mpi_free(&rprime); 261 mbedtls_mpi_free(&sprime); 262 mbedtls_mpi_free(&t); 263 mbedtls_mpi_free(&eprime); 264 mbedtls_mpi_free(&R); 265 return res; 266 } 267