0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <crypto/internal/akcipher.h>
0008 #include <crypto/internal/ecc.h>
0009 #include <crypto/akcipher.h>
0010 #include <crypto/ecdh.h>
0011 #include <linux/asn1_decoder.h>
0012 #include <linux/scatterlist.h>
0013
0014 #include "ecdsasignature.asn1.h"
0015
0016 struct ecc_ctx {
0017 unsigned int curve_id;
0018 const struct ecc_curve *curve;
0019
0020 bool pub_key_set;
0021 u64 x[ECC_MAX_DIGITS];
0022 u64 y[ECC_MAX_DIGITS];
0023 struct ecc_point pub_key;
0024 };
0025
0026 struct ecdsa_signature_ctx {
0027 const struct ecc_curve *curve;
0028 u64 r[ECC_MAX_DIGITS];
0029 u64 s[ECC_MAX_DIGITS];
0030 };
0031
0032
0033
0034
0035 static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
0036 const void *value, size_t vlen, unsigned int ndigits)
0037 {
0038 size_t keylen = ndigits * sizeof(u64);
0039 ssize_t diff = vlen - keylen;
0040 const char *d = value;
0041 u8 rs[ECC_MAX_BYTES];
0042
0043 if (!value || !vlen)
0044 return -EINVAL;
0045
0046
0047
0048
0049
0050
0051 if (diff > 0) {
0052
0053 if (*d == 0) {
0054 vlen -= 1;
0055 diff--;
0056 d++;
0057 }
0058 if (diff)
0059 return -EINVAL;
0060 }
0061 if (-diff >= keylen)
0062 return -EINVAL;
0063
0064 if (diff) {
0065
0066 memset(rs, 0, -diff);
0067 }
0068
0069 memcpy(&rs[-diff], d, vlen);
0070
0071 ecc_swap_digits((u64 *)rs, dest, ndigits);
0072
0073 return 0;
0074 }
0075
0076 int ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag,
0077 const void *value, size_t vlen)
0078 {
0079 struct ecdsa_signature_ctx *sig = context;
0080
0081 return ecdsa_get_signature_rs(sig->r, hdrlen, tag, value, vlen,
0082 sig->curve->g.ndigits);
0083 }
0084
0085 int ecdsa_get_signature_s(void *context, size_t hdrlen, unsigned char tag,
0086 const void *value, size_t vlen)
0087 {
0088 struct ecdsa_signature_ctx *sig = context;
0089
0090 return ecdsa_get_signature_rs(sig->s, hdrlen, tag, value, vlen,
0091 sig->curve->g.ndigits);
0092 }
0093
0094 static int _ecdsa_verify(struct ecc_ctx *ctx, const u64 *hash, const u64 *r, const u64 *s)
0095 {
0096 const struct ecc_curve *curve = ctx->curve;
0097 unsigned int ndigits = curve->g.ndigits;
0098 u64 s1[ECC_MAX_DIGITS];
0099 u64 u1[ECC_MAX_DIGITS];
0100 u64 u2[ECC_MAX_DIGITS];
0101 u64 x1[ECC_MAX_DIGITS];
0102 u64 y1[ECC_MAX_DIGITS];
0103 struct ecc_point res = ECC_POINT_INIT(x1, y1, ndigits);
0104
0105
0106 if (vli_is_zero(r, ndigits) || vli_cmp(r, curve->n, ndigits) >= 0 ||
0107 vli_is_zero(s, ndigits) || vli_cmp(s, curve->n, ndigits) >= 0)
0108 return -EBADMSG;
0109
0110
0111 pr_devel("hash : %016llx %016llx ... %016llx\n",
0112 hash[ndigits - 1], hash[ndigits - 2], hash[0]);
0113
0114
0115 vli_mod_inv(s1, s, curve->n, ndigits);
0116
0117 vli_mod_mult_slow(u1, hash, s1, curve->n, ndigits);
0118
0119 vli_mod_mult_slow(u2, r, s1, curve->n, ndigits);
0120
0121 ecc_point_mult_shamir(&res, u1, &curve->g, u2, &ctx->pub_key, curve);
0122
0123
0124 if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1))
0125
0126 vli_sub(res.x, res.x, curve->n, ndigits);
0127
0128 if (!vli_cmp(res.x, r, ndigits))
0129 return 0;
0130
0131 return -EKEYREJECTED;
0132 }
0133
0134
0135
0136
0137 static int ecdsa_verify(struct akcipher_request *req)
0138 {
0139 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
0140 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0141 size_t keylen = ctx->curve->g.ndigits * sizeof(u64);
0142 struct ecdsa_signature_ctx sig_ctx = {
0143 .curve = ctx->curve,
0144 };
0145 u8 rawhash[ECC_MAX_BYTES];
0146 u64 hash[ECC_MAX_DIGITS];
0147 unsigned char *buffer;
0148 ssize_t diff;
0149 int ret;
0150
0151 if (unlikely(!ctx->pub_key_set))
0152 return -EINVAL;
0153
0154 buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
0155 if (!buffer)
0156 return -ENOMEM;
0157
0158 sg_pcopy_to_buffer(req->src,
0159 sg_nents_for_len(req->src, req->src_len + req->dst_len),
0160 buffer, req->src_len + req->dst_len, 0);
0161
0162 ret = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx,
0163 buffer, req->src_len);
0164 if (ret < 0)
0165 goto error;
0166
0167
0168 diff = keylen - req->dst_len;
0169 if (diff >= 0) {
0170 if (diff)
0171 memset(rawhash, 0, diff);
0172 memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len);
0173 } else if (diff < 0) {
0174
0175 memcpy(&rawhash, buffer + req->src_len, keylen);
0176 }
0177
0178 ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits);
0179
0180 ret = _ecdsa_verify(ctx, hash, sig_ctx.r, sig_ctx.s);
0181
0182 error:
0183 kfree(buffer);
0184
0185 return ret;
0186 }
0187
0188 static int ecdsa_ecc_ctx_init(struct ecc_ctx *ctx, unsigned int curve_id)
0189 {
0190 ctx->curve_id = curve_id;
0191 ctx->curve = ecc_get_curve(curve_id);
0192 if (!ctx->curve)
0193 return -EINVAL;
0194
0195 return 0;
0196 }
0197
0198
0199 static void ecdsa_ecc_ctx_deinit(struct ecc_ctx *ctx)
0200 {
0201 ctx->pub_key_set = false;
0202 }
0203
0204 static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx)
0205 {
0206 unsigned int curve_id = ctx->curve_id;
0207 int ret;
0208
0209 ecdsa_ecc_ctx_deinit(ctx);
0210 ret = ecdsa_ecc_ctx_init(ctx, curve_id);
0211 if (ret == 0)
0212 ctx->pub_key = ECC_POINT_INIT(ctx->x, ctx->y,
0213 ctx->curve->g.ndigits);
0214 return ret;
0215 }
0216
0217
0218
0219
0220
0221
0222 static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen)
0223 {
0224 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0225 const unsigned char *d = key;
0226 const u64 *digits = (const u64 *)&d[1];
0227 unsigned int ndigits;
0228 int ret;
0229
0230 ret = ecdsa_ecc_ctx_reset(ctx);
0231 if (ret < 0)
0232 return ret;
0233
0234 if (keylen < 1 || (((keylen - 1) >> 1) % sizeof(u64)) != 0)
0235 return -EINVAL;
0236
0237 if (d[0] != 4)
0238 return -EINVAL;
0239
0240 keylen--;
0241 ndigits = (keylen >> 1) / sizeof(u64);
0242 if (ndigits != ctx->curve->g.ndigits)
0243 return -EINVAL;
0244
0245 ecc_swap_digits(digits, ctx->pub_key.x, ndigits);
0246 ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits);
0247 ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
0248
0249 ctx->pub_key_set = ret == 0;
0250
0251 return ret;
0252 }
0253
0254 static void ecdsa_exit_tfm(struct crypto_akcipher *tfm)
0255 {
0256 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0257
0258 ecdsa_ecc_ctx_deinit(ctx);
0259 }
0260
0261 static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm)
0262 {
0263 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0264
0265 return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
0266 }
0267
0268 static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
0269 {
0270 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0271
0272 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P384);
0273 }
0274
0275 static struct akcipher_alg ecdsa_nist_p384 = {
0276 .verify = ecdsa_verify,
0277 .set_pub_key = ecdsa_set_pub_key,
0278 .max_size = ecdsa_max_size,
0279 .init = ecdsa_nist_p384_init_tfm,
0280 .exit = ecdsa_exit_tfm,
0281 .base = {
0282 .cra_name = "ecdsa-nist-p384",
0283 .cra_driver_name = "ecdsa-nist-p384-generic",
0284 .cra_priority = 100,
0285 .cra_module = THIS_MODULE,
0286 .cra_ctxsize = sizeof(struct ecc_ctx),
0287 },
0288 };
0289
0290 static int ecdsa_nist_p256_init_tfm(struct crypto_akcipher *tfm)
0291 {
0292 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0293
0294 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P256);
0295 }
0296
0297 static struct akcipher_alg ecdsa_nist_p256 = {
0298 .verify = ecdsa_verify,
0299 .set_pub_key = ecdsa_set_pub_key,
0300 .max_size = ecdsa_max_size,
0301 .init = ecdsa_nist_p256_init_tfm,
0302 .exit = ecdsa_exit_tfm,
0303 .base = {
0304 .cra_name = "ecdsa-nist-p256",
0305 .cra_driver_name = "ecdsa-nist-p256-generic",
0306 .cra_priority = 100,
0307 .cra_module = THIS_MODULE,
0308 .cra_ctxsize = sizeof(struct ecc_ctx),
0309 },
0310 };
0311
0312 static int ecdsa_nist_p192_init_tfm(struct crypto_akcipher *tfm)
0313 {
0314 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
0315
0316 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P192);
0317 }
0318
0319 static struct akcipher_alg ecdsa_nist_p192 = {
0320 .verify = ecdsa_verify,
0321 .set_pub_key = ecdsa_set_pub_key,
0322 .max_size = ecdsa_max_size,
0323 .init = ecdsa_nist_p192_init_tfm,
0324 .exit = ecdsa_exit_tfm,
0325 .base = {
0326 .cra_name = "ecdsa-nist-p192",
0327 .cra_driver_name = "ecdsa-nist-p192-generic",
0328 .cra_priority = 100,
0329 .cra_module = THIS_MODULE,
0330 .cra_ctxsize = sizeof(struct ecc_ctx),
0331 },
0332 };
0333 static bool ecdsa_nist_p192_registered;
0334
0335 static int ecdsa_init(void)
0336 {
0337 int ret;
0338
0339
0340 ret = crypto_register_akcipher(&ecdsa_nist_p192);
0341 ecdsa_nist_p192_registered = ret == 0;
0342
0343 ret = crypto_register_akcipher(&ecdsa_nist_p256);
0344 if (ret)
0345 goto nist_p256_error;
0346
0347 ret = crypto_register_akcipher(&ecdsa_nist_p384);
0348 if (ret)
0349 goto nist_p384_error;
0350
0351 return 0;
0352
0353 nist_p384_error:
0354 crypto_unregister_akcipher(&ecdsa_nist_p256);
0355
0356 nist_p256_error:
0357 if (ecdsa_nist_p192_registered)
0358 crypto_unregister_akcipher(&ecdsa_nist_p192);
0359 return ret;
0360 }
0361
0362 static void ecdsa_exit(void)
0363 {
0364 if (ecdsa_nist_p192_registered)
0365 crypto_unregister_akcipher(&ecdsa_nist_p192);
0366 crypto_unregister_akcipher(&ecdsa_nist_p256);
0367 crypto_unregister_akcipher(&ecdsa_nist_p384);
0368 }
0369
0370 subsys_initcall(ecdsa_init);
0371 module_exit(ecdsa_exit);
0372
0373 MODULE_LICENSE("GPL");
0374 MODULE_AUTHOR("Stefan Berger <stefanb@linux.ibm.com>");
0375 MODULE_DESCRIPTION("ECDSA generic algorithm");
0376 MODULE_ALIAS_CRYPTO("ecdsa-generic");