1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * SM2 asymmetric public-key algorithm 4 * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and 5 * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02 6 * 7 * Copyright (c) 2020, Alibaba Group. 8 * Authors: Tianjia Zhang <tianjia.zhang@linux.alibaba.com> 9 */ 10 11 #include <linux/module.h> 12 #include <linux/mpi.h> 13 #include <crypto/internal/akcipher.h> 14 #include <crypto/akcipher.h> 15 #include <crypto/hash.h> 16 #include <crypto/sm3_base.h> 17 #include <crypto/rng.h> 18 #include <crypto/sm2.h> 19 #include "sm2signature.asn1.h" 20 21 #define MPI_NBYTES(m) ((mpi_get_nbits(m) + 7) / 8) 22 23 struct ecc_domain_parms { 24 const char *desc; /* Description of the curve. */ 25 unsigned int nbits; /* Number of bits. */ 26 unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */ 27 28 /* The model describing this curve. This is mainly used to select 29 * the group equation. 30 */ 31 enum gcry_mpi_ec_models model; 32 33 /* The actual ECC dialect used. This is used for curve specific 34 * optimizations and to select encodings etc. 35 */ 36 enum ecc_dialects dialect; 37 38 const char *p; /* The prime defining the field. */ 39 const char *a, *b; /* The coefficients. For Twisted Edwards 40 * Curves b is used for d. For Montgomery 41 * Curves (a,b) has ((A-2)/4,B^-1). 42 */ 43 const char *n; /* The order of the base point. */ 44 const char *g_x, *g_y; /* Base point. */ 45 unsigned int h; /* Cofactor. */ 46 }; 47 48 static const struct ecc_domain_parms sm2_ecp = { 49 .desc = "sm2p256v1", 50 .nbits = 256, 51 .fips = 0, 52 .model = MPI_EC_WEIERSTRASS, 53 .dialect = ECC_DIALECT_STANDARD, 54 .p = "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff", 55 .a = "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc", 56 .b = "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93", 57 .n = "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123", 58 .g_x = "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7", 59 .g_y = "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0", 60 .h = 1 61 }; 62 63 static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec) 64 { 65 const struct ecc_domain_parms *ecp = &sm2_ecp; 66 MPI p, a, b; 67 MPI x, y; 68 int rc = -EINVAL; 69 70 p = mpi_scanval(ecp->p); 71 a = mpi_scanval(ecp->a); 72 b = mpi_scanval(ecp->b); 73 if (!p || !a || !b) 74 goto free_p; 75 76 x = mpi_scanval(ecp->g_x); 77 y = mpi_scanval(ecp->g_y); 78 if (!x || !y) 79 goto free; 80 81 rc = -ENOMEM; 82 /* mpi_ec_setup_elliptic_curve */ 83 ec->G = mpi_point_new(0); 84 if (!ec->G) 85 goto free; 86 87 mpi_set(ec->G->x, x); 88 mpi_set(ec->G->y, y); 89 mpi_set_ui(ec->G->z, 1); 90 91 rc = -EINVAL; 92 ec->n = mpi_scanval(ecp->n); 93 if (!ec->n) { 94 mpi_point_release(ec->G); 95 goto free; 96 } 97 98 ec->h = ecp->h; 99 ec->name = ecp->desc; 100 mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b); 101 102 rc = 0; 103 104 free: 105 mpi_free(x); 106 mpi_free(y); 107 free_p: 108 mpi_free(p); 109 mpi_free(a); 110 mpi_free(b); 111 112 return rc; 113 } 114 115 static void sm2_ec_ctx_deinit(struct mpi_ec_ctx *ec) 116 { 117 mpi_ec_deinit(ec); 118 119 memset(ec, 0, sizeof(*ec)); 120 } 121 122 /* RESULT must have been initialized and is set on success to the 123 * point given by VALUE. 124 */ 125 static int sm2_ecc_os2ec(MPI_POINT result, MPI value) 126 { 127 int rc; 128 size_t n; 129 unsigned char *buf; 130 MPI x, y; 131 132 n = MPI_NBYTES(value); 133 buf = kmalloc(n, GFP_KERNEL); 134 if (!buf) 135 return -ENOMEM; 136 137 rc = mpi_print(GCRYMPI_FMT_USG, buf, n, &n, value); 138 if (rc) 139 goto err_freebuf; 140 141 rc = -EINVAL; 142 if (n < 1 || ((n - 1) % 2)) 143 goto err_freebuf; 144 /* No support for point compression */ 145 if (*buf != 0x4) 146 goto err_freebuf; 147 148 rc = -ENOMEM; 149 n = (n - 1) / 2; 150 x = mpi_read_raw_data(buf + 1, n); 151 if (!x) 152 goto err_freebuf; 153 y = mpi_read_raw_data(buf + 1 + n, n); 154 if (!y) 155 goto err_freex; 156 157 mpi_normalize(x); 158 mpi_normalize(y); 159 mpi_set(result->x, x); 160 mpi_set(result->y, y); 161 mpi_set_ui(result->z, 1); 162 163 rc = 0; 164 165 mpi_free(y); 166 err_freex: 167 mpi_free(x); 168 err_freebuf: 169 kfree(buf); 170 return rc; 171 } 172 173 struct sm2_signature_ctx { 174 MPI sig_r; 175 MPI sig_s; 176 }; 177 178 int sm2_get_signature_r(void *context, size_t hdrlen, unsigned char tag, 179 const void *value, size_t vlen) 180 { 181 struct sm2_signature_ctx *sig = context; 182 183 if (!value || !vlen) 184 return -EINVAL; 185 186 sig->sig_r = mpi_read_raw_data(value, vlen); 187 if (!sig->sig_r) 188 return -ENOMEM; 189 190 return 0; 191 } 192 193 int sm2_get_signature_s(void *context, size_t hdrlen, unsigned char tag, 194 const void *value, size_t vlen) 195 { 196 struct sm2_signature_ctx *sig = context; 197 198 if (!value || !vlen) 199 return -EINVAL; 200 201 sig->sig_s = mpi_read_raw_data(value, vlen); 202 if (!sig->sig_s) 203 return -ENOMEM; 204 205 return 0; 206 } 207 208 static int sm2_z_digest_update(struct shash_desc *desc, 209 MPI m, unsigned int pbytes) 210 { 211 static const unsigned char zero[32]; 212 unsigned char *in; 213 unsigned int inlen; 214 215 in = mpi_get_buffer(m, &inlen, NULL); 216 if (!in) 217 return -EINVAL; 218 219 if (inlen < pbytes) { 220 /* padding with zero */ 221 crypto_sm3_update(desc, zero, pbytes - inlen); 222 crypto_sm3_update(desc, in, inlen); 223 } else if (inlen > pbytes) { 224 /* skip the starting zero */ 225 crypto_sm3_update(desc, in + inlen - pbytes, pbytes); 226 } else { 227 crypto_sm3_update(desc, in, inlen); 228 } 229 230 kfree(in); 231 return 0; 232 } 233 234 static int sm2_z_digest_update_point(struct shash_desc *desc, 235 MPI_POINT point, struct mpi_ec_ctx *ec, unsigned int pbytes) 236 { 237 MPI x, y; 238 int ret = -EINVAL; 239 240 x = mpi_new(0); 241 y = mpi_new(0); 242 243 if (!mpi_ec_get_affine(x, y, point, ec) && 244 !sm2_z_digest_update(desc, x, pbytes) && 245 !sm2_z_digest_update(desc, y, pbytes)) 246 ret = 0; 247 248 mpi_free(x); 249 mpi_free(y); 250 return ret; 251 } 252 253 int sm2_compute_z_digest(struct crypto_akcipher *tfm, 254 const unsigned char *id, size_t id_len, 255 unsigned char dgst[SM3_DIGEST_SIZE]) 256 { 257 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 258 uint16_t bits_len; 259 unsigned char entl[2]; 260 SHASH_DESC_ON_STACK(desc, NULL); 261 unsigned int pbytes; 262 263 if (id_len > (USHRT_MAX / 8) || !ec->Q) 264 return -EINVAL; 265 266 bits_len = (uint16_t)(id_len * 8); 267 entl[0] = bits_len >> 8; 268 entl[1] = bits_len & 0xff; 269 270 pbytes = MPI_NBYTES(ec->p); 271 272 /* ZA = H256(ENTLA | IDA | a | b | xG | yG | xA | yA) */ 273 sm3_base_init(desc); 274 crypto_sm3_update(desc, entl, 2); 275 crypto_sm3_update(desc, id, id_len); 276 277 if (sm2_z_digest_update(desc, ec->a, pbytes) || 278 sm2_z_digest_update(desc, ec->b, pbytes) || 279 sm2_z_digest_update_point(desc, ec->G, ec, pbytes) || 280 sm2_z_digest_update_point(desc, ec->Q, ec, pbytes)) 281 return -EINVAL; 282 283 crypto_sm3_final(desc, dgst); 284 return 0; 285 } 286 EXPORT_SYMBOL(sm2_compute_z_digest); 287 288 static int _sm2_verify(struct mpi_ec_ctx *ec, MPI hash, MPI sig_r, MPI sig_s) 289 { 290 int rc = -EINVAL; 291 struct gcry_mpi_point sG, tP; 292 MPI t = NULL; 293 MPI x1 = NULL, y1 = NULL; 294 295 mpi_point_init(&sG); 296 mpi_point_init(&tP); 297 x1 = mpi_new(0); 298 y1 = mpi_new(0); 299 t = mpi_new(0); 300 301 /* r, s in [1, n-1] */ 302 if (mpi_cmp_ui(sig_r, 1) < 0 || mpi_cmp(sig_r, ec->n) > 0 || 303 mpi_cmp_ui(sig_s, 1) < 0 || mpi_cmp(sig_s, ec->n) > 0) { 304 goto leave; 305 } 306 307 /* t = (r + s) % n, t == 0 */ 308 mpi_addm(t, sig_r, sig_s, ec->n); 309 if (mpi_cmp_ui(t, 0) == 0) 310 goto leave; 311 312 /* sG + tP = (x1, y1) */ 313 rc = -EBADMSG; 314 mpi_ec_mul_point(&sG, sig_s, ec->G, ec); 315 mpi_ec_mul_point(&tP, t, ec->Q, ec); 316 mpi_ec_add_points(&sG, &sG, &tP, ec); 317 if (mpi_ec_get_affine(x1, y1, &sG, ec)) 318 goto leave; 319 320 /* R = (e + x1) % n */ 321 mpi_addm(t, hash, x1, ec->n); 322 323 /* check R == r */ 324 rc = -EKEYREJECTED; 325 if (mpi_cmp(t, sig_r)) 326 goto leave; 327 328 rc = 0; 329 330 leave: 331 mpi_point_free_parts(&sG); 332 mpi_point_free_parts(&tP); 333 mpi_free(x1); 334 mpi_free(y1); 335 mpi_free(t); 336 337 return rc; 338 } 339 340 static int sm2_verify(struct akcipher_request *req) 341 { 342 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 343 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 344 unsigned char *buffer; 345 struct sm2_signature_ctx sig; 346 MPI hash; 347 int ret; 348 349 if (unlikely(!ec->Q)) 350 return -EINVAL; 351 352 buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL); 353 if (!buffer) 354 return -ENOMEM; 355 356 sg_pcopy_to_buffer(req->src, 357 sg_nents_for_len(req->src, req->src_len + req->dst_len), 358 buffer, req->src_len + req->dst_len, 0); 359 360 sig.sig_r = NULL; 361 sig.sig_s = NULL; 362 ret = asn1_ber_decoder(&sm2signature_decoder, &sig, 363 buffer, req->src_len); 364 if (ret) 365 goto error; 366 367 ret = -ENOMEM; 368 hash = mpi_read_raw_data(buffer + req->src_len, req->dst_len); 369 if (!hash) 370 goto error; 371 372 ret = _sm2_verify(ec, hash, sig.sig_r, sig.sig_s); 373 374 mpi_free(hash); 375 error: 376 mpi_free(sig.sig_r); 377 mpi_free(sig.sig_s); 378 kfree(buffer); 379 return ret; 380 } 381 382 static int sm2_set_pub_key(struct crypto_akcipher *tfm, 383 const void *key, unsigned int keylen) 384 { 385 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 386 MPI a; 387 int rc; 388 389 ec->Q = mpi_point_new(0); 390 if (!ec->Q) 391 return -ENOMEM; 392 393 /* include the uncompressed flag '0x04' */ 394 rc = -ENOMEM; 395 a = mpi_read_raw_data(key, keylen); 396 if (!a) 397 goto error; 398 399 mpi_normalize(a); 400 rc = sm2_ecc_os2ec(ec->Q, a); 401 mpi_free(a); 402 if (rc) 403 goto error; 404 405 return 0; 406 407 error: 408 mpi_point_release(ec->Q); 409 ec->Q = NULL; 410 return rc; 411 } 412 413 static unsigned int sm2_max_size(struct crypto_akcipher *tfm) 414 { 415 /* Unlimited max size */ 416 return PAGE_SIZE; 417 } 418 419 static int sm2_init_tfm(struct crypto_akcipher *tfm) 420 { 421 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 422 423 return sm2_ec_ctx_init(ec); 424 } 425 426 static void sm2_exit_tfm(struct crypto_akcipher *tfm) 427 { 428 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 429 430 sm2_ec_ctx_deinit(ec); 431 } 432 433 static struct akcipher_alg sm2 = { 434 .verify = sm2_verify, 435 .set_pub_key = sm2_set_pub_key, 436 .max_size = sm2_max_size, 437 .init = sm2_init_tfm, 438 .exit = sm2_exit_tfm, 439 .base = { 440 .cra_name = "sm2", 441 .cra_driver_name = "sm2-generic", 442 .cra_priority = 100, 443 .cra_module = THIS_MODULE, 444 .cra_ctxsize = sizeof(struct mpi_ec_ctx), 445 }, 446 }; 447 448 static int sm2_init(void) 449 { 450 return crypto_register_akcipher(&sm2); 451 } 452 453 static void sm2_exit(void) 454 { 455 crypto_unregister_akcipher(&sm2); 456 } 457 458 subsys_initcall(sm2_init); 459 module_exit(sm2_exit); 460 461 MODULE_LICENSE("GPL"); 462 MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>"); 463 MODULE_DESCRIPTION("SM2 generic algorithm"); 464 MODULE_ALIAS_CRYPTO("sm2-generic"); 465