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 static int sm2_ec_ctx_reset(struct mpi_ec_ctx *ec) 123 { 124 sm2_ec_ctx_deinit(ec); 125 return sm2_ec_ctx_init(ec); 126 } 127 128 /* RESULT must have been initialized and is set on success to the 129 * point given by VALUE. 130 */ 131 static int sm2_ecc_os2ec(MPI_POINT result, MPI value) 132 { 133 int rc; 134 size_t n; 135 const unsigned char *buf; 136 unsigned char *buf_memory; 137 MPI x, y; 138 139 n = (mpi_get_nbits(value)+7)/8; 140 buf_memory = kmalloc(n, GFP_KERNEL); 141 rc = mpi_print(GCRYMPI_FMT_USG, buf_memory, n, &n, value); 142 if (rc) { 143 kfree(buf_memory); 144 return rc; 145 } 146 buf = buf_memory; 147 148 if (n < 1) { 149 kfree(buf_memory); 150 return -EINVAL; 151 } 152 if (*buf != 4) { 153 kfree(buf_memory); 154 return -EINVAL; /* No support for point compression. */ 155 } 156 if (((n-1)%2)) { 157 kfree(buf_memory); 158 return -EINVAL; 159 } 160 n = (n-1)/2; 161 x = mpi_read_raw_data(buf + 1, n); 162 if (!x) { 163 kfree(buf_memory); 164 return -ENOMEM; 165 } 166 y = mpi_read_raw_data(buf + 1 + n, n); 167 kfree(buf_memory); 168 if (!y) { 169 mpi_free(x); 170 return -ENOMEM; 171 } 172 173 mpi_normalize(x); 174 mpi_normalize(y); 175 176 mpi_set(result->x, x); 177 mpi_set(result->y, y); 178 mpi_set_ui(result->z, 1); 179 180 mpi_free(x); 181 mpi_free(y); 182 183 return 0; 184 } 185 186 struct sm2_signature_ctx { 187 MPI sig_r; 188 MPI sig_s; 189 }; 190 191 int sm2_get_signature_r(void *context, size_t hdrlen, unsigned char tag, 192 const void *value, size_t vlen) 193 { 194 struct sm2_signature_ctx *sig = context; 195 196 if (!value || !vlen) 197 return -EINVAL; 198 199 sig->sig_r = mpi_read_raw_data(value, vlen); 200 if (!sig->sig_r) 201 return -ENOMEM; 202 203 return 0; 204 } 205 206 int sm2_get_signature_s(void *context, size_t hdrlen, unsigned char tag, 207 const void *value, size_t vlen) 208 { 209 struct sm2_signature_ctx *sig = context; 210 211 if (!value || !vlen) 212 return -EINVAL; 213 214 sig->sig_s = mpi_read_raw_data(value, vlen); 215 if (!sig->sig_s) 216 return -ENOMEM; 217 218 return 0; 219 } 220 221 static int sm2_z_digest_update(struct shash_desc *desc, 222 MPI m, unsigned int pbytes) 223 { 224 static const unsigned char zero[32]; 225 unsigned char *in; 226 unsigned int inlen; 227 228 in = mpi_get_buffer(m, &inlen, NULL); 229 if (!in) 230 return -EINVAL; 231 232 if (inlen < pbytes) { 233 /* padding with zero */ 234 crypto_sm3_update(desc, zero, pbytes - inlen); 235 crypto_sm3_update(desc, in, inlen); 236 } else if (inlen > pbytes) { 237 /* skip the starting zero */ 238 crypto_sm3_update(desc, in + inlen - pbytes, pbytes); 239 } else { 240 crypto_sm3_update(desc, in, inlen); 241 } 242 243 kfree(in); 244 return 0; 245 } 246 247 static int sm2_z_digest_update_point(struct shash_desc *desc, 248 MPI_POINT point, struct mpi_ec_ctx *ec, unsigned int pbytes) 249 { 250 MPI x, y; 251 int ret = -EINVAL; 252 253 x = mpi_new(0); 254 y = mpi_new(0); 255 256 if (!mpi_ec_get_affine(x, y, point, ec) && 257 !sm2_z_digest_update(desc, x, pbytes) && 258 !sm2_z_digest_update(desc, y, pbytes)) 259 ret = 0; 260 261 mpi_free(x); 262 mpi_free(y); 263 return ret; 264 } 265 266 int sm2_compute_z_digest(struct crypto_akcipher *tfm, 267 const unsigned char *id, size_t id_len, 268 unsigned char dgst[SM3_DIGEST_SIZE]) 269 { 270 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 271 uint16_t bits_len; 272 unsigned char entl[2]; 273 SHASH_DESC_ON_STACK(desc, NULL); 274 unsigned int pbytes; 275 276 if (id_len > (USHRT_MAX / 8) || !ec->Q) 277 return -EINVAL; 278 279 bits_len = (uint16_t)(id_len * 8); 280 entl[0] = bits_len >> 8; 281 entl[1] = bits_len & 0xff; 282 283 pbytes = MPI_NBYTES(ec->p); 284 285 /* ZA = H256(ENTLA | IDA | a | b | xG | yG | xA | yA) */ 286 sm3_base_init(desc); 287 crypto_sm3_update(desc, entl, 2); 288 crypto_sm3_update(desc, id, id_len); 289 290 if (sm2_z_digest_update(desc, ec->a, pbytes) || 291 sm2_z_digest_update(desc, ec->b, pbytes) || 292 sm2_z_digest_update_point(desc, ec->G, ec, pbytes) || 293 sm2_z_digest_update_point(desc, ec->Q, ec, pbytes)) 294 return -EINVAL; 295 296 crypto_sm3_final(desc, dgst); 297 return 0; 298 } 299 EXPORT_SYMBOL(sm2_compute_z_digest); 300 301 static int _sm2_verify(struct mpi_ec_ctx *ec, MPI hash, MPI sig_r, MPI sig_s) 302 { 303 int rc = -EINVAL; 304 struct gcry_mpi_point sG, tP; 305 MPI t = NULL; 306 MPI x1 = NULL, y1 = NULL; 307 308 mpi_point_init(&sG); 309 mpi_point_init(&tP); 310 x1 = mpi_new(0); 311 y1 = mpi_new(0); 312 t = mpi_new(0); 313 314 /* r, s in [1, n-1] */ 315 if (mpi_cmp_ui(sig_r, 1) < 0 || mpi_cmp(sig_r, ec->n) > 0 || 316 mpi_cmp_ui(sig_s, 1) < 0 || mpi_cmp(sig_s, ec->n) > 0) { 317 goto leave; 318 } 319 320 /* t = (r + s) % n, t == 0 */ 321 mpi_addm(t, sig_r, sig_s, ec->n); 322 if (mpi_cmp_ui(t, 0) == 0) 323 goto leave; 324 325 /* sG + tP = (x1, y1) */ 326 rc = -EBADMSG; 327 mpi_ec_mul_point(&sG, sig_s, ec->G, ec); 328 mpi_ec_mul_point(&tP, t, ec->Q, ec); 329 mpi_ec_add_points(&sG, &sG, &tP, ec); 330 if (mpi_ec_get_affine(x1, y1, &sG, ec)) 331 goto leave; 332 333 /* R = (e + x1) % n */ 334 mpi_addm(t, hash, x1, ec->n); 335 336 /* check R == r */ 337 rc = -EKEYREJECTED; 338 if (mpi_cmp(t, sig_r)) 339 goto leave; 340 341 rc = 0; 342 343 leave: 344 mpi_point_free_parts(&sG); 345 mpi_point_free_parts(&tP); 346 mpi_free(x1); 347 mpi_free(y1); 348 mpi_free(t); 349 350 return rc; 351 } 352 353 static int sm2_verify(struct akcipher_request *req) 354 { 355 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 356 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 357 unsigned char *buffer; 358 struct sm2_signature_ctx sig; 359 MPI hash; 360 int ret; 361 362 if (unlikely(!ec->Q)) 363 return -EINVAL; 364 365 buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL); 366 if (!buffer) 367 return -ENOMEM; 368 369 sg_pcopy_to_buffer(req->src, 370 sg_nents_for_len(req->src, req->src_len + req->dst_len), 371 buffer, req->src_len + req->dst_len, 0); 372 373 sig.sig_r = NULL; 374 sig.sig_s = NULL; 375 ret = asn1_ber_decoder(&sm2signature_decoder, &sig, 376 buffer, req->src_len); 377 if (ret) 378 goto error; 379 380 ret = -ENOMEM; 381 hash = mpi_read_raw_data(buffer + req->src_len, req->dst_len); 382 if (!hash) 383 goto error; 384 385 ret = _sm2_verify(ec, hash, sig.sig_r, sig.sig_s); 386 387 mpi_free(hash); 388 error: 389 mpi_free(sig.sig_r); 390 mpi_free(sig.sig_s); 391 kfree(buffer); 392 return ret; 393 } 394 395 static int sm2_set_pub_key(struct crypto_akcipher *tfm, 396 const void *key, unsigned int keylen) 397 { 398 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 399 MPI a; 400 int rc; 401 402 rc = sm2_ec_ctx_reset(ec); 403 if (rc) 404 return rc; 405 406 ec->Q = mpi_point_new(0); 407 if (!ec->Q) 408 return -ENOMEM; 409 410 /* include the uncompressed flag '0x04' */ 411 rc = -ENOMEM; 412 a = mpi_read_raw_data(key, keylen); 413 if (!a) 414 goto error; 415 416 mpi_normalize(a); 417 rc = sm2_ecc_os2ec(ec->Q, a); 418 mpi_free(a); 419 if (rc) 420 goto error; 421 422 return 0; 423 424 error: 425 mpi_point_release(ec->Q); 426 ec->Q = NULL; 427 return rc; 428 } 429 430 static unsigned int sm2_max_size(struct crypto_akcipher *tfm) 431 { 432 /* Unlimited max size */ 433 return PAGE_SIZE; 434 } 435 436 static int sm2_init_tfm(struct crypto_akcipher *tfm) 437 { 438 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 439 440 return sm2_ec_ctx_init(ec); 441 } 442 443 static void sm2_exit_tfm(struct crypto_akcipher *tfm) 444 { 445 struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm); 446 447 sm2_ec_ctx_deinit(ec); 448 } 449 450 static struct akcipher_alg sm2 = { 451 .verify = sm2_verify, 452 .set_pub_key = sm2_set_pub_key, 453 .max_size = sm2_max_size, 454 .init = sm2_init_tfm, 455 .exit = sm2_exit_tfm, 456 .base = { 457 .cra_name = "sm2", 458 .cra_driver_name = "sm2-generic", 459 .cra_priority = 100, 460 .cra_module = THIS_MODULE, 461 .cra_ctxsize = sizeof(struct mpi_ec_ctx), 462 }, 463 }; 464 465 static int sm2_init(void) 466 { 467 return crypto_register_akcipher(&sm2); 468 } 469 470 static void sm2_exit(void) 471 { 472 crypto_unregister_akcipher(&sm2); 473 } 474 475 subsys_initcall(sm2_init); 476 module_exit(sm2_exit); 477 478 MODULE_LICENSE("GPL"); 479 MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>"); 480 MODULE_DESCRIPTION("SM2 generic algorithm"); 481 MODULE_ALIAS_CRYPTO("sm2-generic"); 482