1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 2 /* 3 * Copyright (c) 2021 IBM Corporation 3 * Copyright (c) 2021 IBM Corporation 4 */ 4 */ 5 5 6 #include <linux/module.h> 6 #include <linux/module.h> 7 #include <crypto/internal/akcipher.h> 7 #include <crypto/internal/akcipher.h> 8 #include <crypto/internal/ecc.h> 8 #include <crypto/internal/ecc.h> 9 #include <crypto/akcipher.h> 9 #include <crypto/akcipher.h> 10 #include <crypto/ecdh.h> 10 #include <crypto/ecdh.h> 11 #include <linux/asn1_decoder.h> 11 #include <linux/asn1_decoder.h> 12 #include <linux/scatterlist.h> 12 #include <linux/scatterlist.h> 13 13 14 #include "ecdsasignature.asn1.h" 14 #include "ecdsasignature.asn1.h" 15 15 16 struct ecc_ctx { 16 struct ecc_ctx { 17 unsigned int curve_id; 17 unsigned int curve_id; 18 const struct ecc_curve *curve; 18 const struct ecc_curve *curve; 19 19 20 bool pub_key_set; 20 bool pub_key_set; 21 u64 x[ECC_MAX_DIGITS]; /* pub key x an 21 u64 x[ECC_MAX_DIGITS]; /* pub key x and y coordinates */ 22 u64 y[ECC_MAX_DIGITS]; 22 u64 y[ECC_MAX_DIGITS]; 23 struct ecc_point pub_key; 23 struct ecc_point pub_key; 24 }; 24 }; 25 25 26 struct ecdsa_signature_ctx { 26 struct ecdsa_signature_ctx { 27 const struct ecc_curve *curve; 27 const struct ecc_curve *curve; 28 u64 r[ECC_MAX_DIGITS]; 28 u64 r[ECC_MAX_DIGITS]; 29 u64 s[ECC_MAX_DIGITS]; 29 u64 s[ECC_MAX_DIGITS]; 30 }; 30 }; 31 31 32 /* 32 /* 33 * Get the r and s components of a signature f 33 * Get the r and s components of a signature from the X509 certificate. 34 */ 34 */ 35 static int ecdsa_get_signature_rs(u64 *dest, s 35 static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag, 36 const void * 36 const void *value, size_t vlen, unsigned int ndigits) 37 { 37 { 38 size_t bufsize = ndigits * sizeof(u64) 38 size_t bufsize = ndigits * sizeof(u64); 39 ssize_t diff = vlen - bufsize; 39 ssize_t diff = vlen - bufsize; 40 const char *d = value; 40 const char *d = value; >> 41 u8 rs[ECC_MAX_BYTES]; 41 42 42 if (!value || !vlen) 43 if (!value || !vlen) 43 return -EINVAL; 44 return -EINVAL; 44 45 45 /* diff = 0: 'value' has exacly the ri 46 /* diff = 0: 'value' has exacly the right size 46 * diff > 0: 'value' has too many byte 47 * diff > 0: 'value' has too many bytes; one leading zero is allowed that 47 * makes the value a positiv 48 * makes the value a positive integer; error on more 48 * diff < 0: 'value' is missing leadin !! 49 * diff < 0: 'value' is missing leading zeros, which we add 49 */ 50 */ 50 if (diff > 0) { 51 if (diff > 0) { 51 /* skip over leading zeros tha 52 /* skip over leading zeros that make 'value' a positive int */ 52 if (*d == 0) { 53 if (*d == 0) { 53 vlen -= 1; 54 vlen -= 1; 54 diff--; 55 diff--; 55 d++; 56 d++; 56 } 57 } 57 if (diff) 58 if (diff) 58 return -EINVAL; 59 return -EINVAL; 59 } 60 } 60 if (-diff >= bufsize) 61 if (-diff >= bufsize) 61 return -EINVAL; 62 return -EINVAL; 62 63 63 ecc_digits_from_bytes(d, vlen, dest, n !! 64 if (diff) { >> 65 /* leading zeros not given in 'value' */ >> 66 memset(rs, 0, -diff); >> 67 } >> 68 >> 69 memcpy(&rs[-diff], d, vlen); >> 70 >> 71 ecc_swap_digits((u64 *)rs, dest, ndigits); 64 72 65 return 0; 73 return 0; 66 } 74 } 67 75 68 int ecdsa_get_signature_r(void *context, size_ 76 int ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag, 69 const void *value, s 77 const void *value, size_t vlen) 70 { 78 { 71 struct ecdsa_signature_ctx *sig = cont 79 struct ecdsa_signature_ctx *sig = context; 72 80 73 return ecdsa_get_signature_rs(sig->r, 81 return ecdsa_get_signature_rs(sig->r, hdrlen, tag, value, vlen, 74 sig->cur 82 sig->curve->g.ndigits); 75 } 83 } 76 84 77 int ecdsa_get_signature_s(void *context, size_ 85 int ecdsa_get_signature_s(void *context, size_t hdrlen, unsigned char tag, 78 const void *value, s 86 const void *value, size_t vlen) 79 { 87 { 80 struct ecdsa_signature_ctx *sig = cont 88 struct ecdsa_signature_ctx *sig = context; 81 89 82 return ecdsa_get_signature_rs(sig->s, 90 return ecdsa_get_signature_rs(sig->s, hdrlen, tag, value, vlen, 83 sig->cur 91 sig->curve->g.ndigits); 84 } 92 } 85 93 86 static int _ecdsa_verify(struct ecc_ctx *ctx, 94 static int _ecdsa_verify(struct ecc_ctx *ctx, const u64 *hash, const u64 *r, const u64 *s) 87 { 95 { 88 const struct ecc_curve *curve = ctx->c 96 const struct ecc_curve *curve = ctx->curve; 89 unsigned int ndigits = curve->g.ndigit 97 unsigned int ndigits = curve->g.ndigits; 90 u64 s1[ECC_MAX_DIGITS]; 98 u64 s1[ECC_MAX_DIGITS]; 91 u64 u1[ECC_MAX_DIGITS]; 99 u64 u1[ECC_MAX_DIGITS]; 92 u64 u2[ECC_MAX_DIGITS]; 100 u64 u2[ECC_MAX_DIGITS]; 93 u64 x1[ECC_MAX_DIGITS]; 101 u64 x1[ECC_MAX_DIGITS]; 94 u64 y1[ECC_MAX_DIGITS]; 102 u64 y1[ECC_MAX_DIGITS]; 95 struct ecc_point res = ECC_POINT_INIT( 103 struct ecc_point res = ECC_POINT_INIT(x1, y1, ndigits); 96 104 97 /* 0 < r < n and 0 < s < n */ 105 /* 0 < r < n and 0 < s < n */ 98 if (vli_is_zero(r, ndigits) || vli_cmp 106 if (vli_is_zero(r, ndigits) || vli_cmp(r, curve->n, ndigits) >= 0 || 99 vli_is_zero(s, ndigits) || vli_cmp 107 vli_is_zero(s, ndigits) || vli_cmp(s, curve->n, ndigits) >= 0) 100 return -EBADMSG; 108 return -EBADMSG; 101 109 102 /* hash is given */ 110 /* hash is given */ 103 pr_devel("hash : %016llx %016llx ... % 111 pr_devel("hash : %016llx %016llx ... %016llx\n", 104 hash[ndigits - 1], hash[ndigi 112 hash[ndigits - 1], hash[ndigits - 2], hash[0]); 105 113 106 /* s1 = (s^-1) mod n */ 114 /* s1 = (s^-1) mod n */ 107 vli_mod_inv(s1, s, curve->n, ndigits); 115 vli_mod_inv(s1, s, curve->n, ndigits); 108 /* u1 = (hash * s1) mod n */ 116 /* u1 = (hash * s1) mod n */ 109 vli_mod_mult_slow(u1, hash, s1, curve- 117 vli_mod_mult_slow(u1, hash, s1, curve->n, ndigits); 110 /* u2 = (r * s1) mod n */ 118 /* u2 = (r * s1) mod n */ 111 vli_mod_mult_slow(u2, r, s1, curve->n, 119 vli_mod_mult_slow(u2, r, s1, curve->n, ndigits); 112 /* res = u1*G + u2 * pub_key */ 120 /* res = u1*G + u2 * pub_key */ 113 ecc_point_mult_shamir(&res, u1, &curve 121 ecc_point_mult_shamir(&res, u1, &curve->g, u2, &ctx->pub_key, curve); 114 122 115 /* res.x = res.x mod n (if res.x > ord 123 /* res.x = res.x mod n (if res.x > order) */ 116 if (unlikely(vli_cmp(res.x, curve->n, 124 if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1)) 117 /* faster alternative for NIST 125 /* faster alternative for NIST p521, p384, p256 & p192 */ 118 vli_sub(res.x, res.x, curve->n 126 vli_sub(res.x, res.x, curve->n, ndigits); 119 127 120 if (!vli_cmp(res.x, r, ndigits)) 128 if (!vli_cmp(res.x, r, ndigits)) 121 return 0; 129 return 0; 122 130 123 return -EKEYREJECTED; 131 return -EKEYREJECTED; 124 } 132 } 125 133 126 /* 134 /* 127 * Verify an ECDSA signature. 135 * Verify an ECDSA signature. 128 */ 136 */ 129 static int ecdsa_verify(struct akcipher_reques 137 static int ecdsa_verify(struct akcipher_request *req) 130 { 138 { 131 struct crypto_akcipher *tfm = crypto_a 139 struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); 132 struct ecc_ctx *ctx = akcipher_tfm_ctx 140 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 133 size_t bufsize = ctx->curve->g.ndigits 141 size_t bufsize = ctx->curve->g.ndigits * sizeof(u64); 134 struct ecdsa_signature_ctx sig_ctx = { 142 struct ecdsa_signature_ctx sig_ctx = { 135 .curve = ctx->curve, 143 .curve = ctx->curve, 136 }; 144 }; >> 145 u8 rawhash[ECC_MAX_BYTES]; 137 u64 hash[ECC_MAX_DIGITS]; 146 u64 hash[ECC_MAX_DIGITS]; 138 unsigned char *buffer; 147 unsigned char *buffer; >> 148 ssize_t diff; 139 int ret; 149 int ret; 140 150 141 if (unlikely(!ctx->pub_key_set)) 151 if (unlikely(!ctx->pub_key_set)) 142 return -EINVAL; 152 return -EINVAL; 143 153 144 buffer = kmalloc(req->src_len + req->d 154 buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL); 145 if (!buffer) 155 if (!buffer) 146 return -ENOMEM; 156 return -ENOMEM; 147 157 148 sg_pcopy_to_buffer(req->src, 158 sg_pcopy_to_buffer(req->src, 149 sg_nents_for_len(req->src, req 159 sg_nents_for_len(req->src, req->src_len + req->dst_len), 150 buffer, req->src_len + req->ds 160 buffer, req->src_len + req->dst_len, 0); 151 161 152 ret = asn1_ber_decoder(&ecdsasignature 162 ret = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx, 153 buffer, req->sr 163 buffer, req->src_len); 154 if (ret < 0) 164 if (ret < 0) 155 goto error; 165 goto error; 156 166 157 if (bufsize > req->dst_len) !! 167 /* if the hash is shorter then we will add leading zeros to fit to ndigits */ 158 bufsize = req->dst_len; !! 168 diff = bufsize - req->dst_len; >> 169 if (diff >= 0) { >> 170 if (diff) >> 171 memset(rawhash, 0, diff); >> 172 memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len); >> 173 } else if (diff < 0) { >> 174 /* given hash is longer, we take the left-most bytes */ >> 175 memcpy(&rawhash, buffer + req->src_len, bufsize); >> 176 } 159 177 160 ecc_digits_from_bytes(buffer + req->sr !! 178 ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits); 161 hash, ctx->curve << 162 179 163 ret = _ecdsa_verify(ctx, hash, sig_ctx 180 ret = _ecdsa_verify(ctx, hash, sig_ctx.r, sig_ctx.s); 164 181 165 error: 182 error: 166 kfree(buffer); 183 kfree(buffer); 167 184 168 return ret; 185 return ret; 169 } 186 } 170 187 171 static int ecdsa_ecc_ctx_init(struct ecc_ctx * 188 static int ecdsa_ecc_ctx_init(struct ecc_ctx *ctx, unsigned int curve_id) 172 { 189 { 173 ctx->curve_id = curve_id; 190 ctx->curve_id = curve_id; 174 ctx->curve = ecc_get_curve(curve_id); 191 ctx->curve = ecc_get_curve(curve_id); 175 if (!ctx->curve) 192 if (!ctx->curve) 176 return -EINVAL; 193 return -EINVAL; 177 194 178 return 0; 195 return 0; 179 } 196 } 180 197 181 198 182 static void ecdsa_ecc_ctx_deinit(struct ecc_ct 199 static void ecdsa_ecc_ctx_deinit(struct ecc_ctx *ctx) 183 { 200 { 184 ctx->pub_key_set = false; 201 ctx->pub_key_set = false; 185 } 202 } 186 203 187 static int ecdsa_ecc_ctx_reset(struct ecc_ctx 204 static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx) 188 { 205 { 189 unsigned int curve_id = ctx->curve_id; 206 unsigned int curve_id = ctx->curve_id; 190 int ret; 207 int ret; 191 208 192 ecdsa_ecc_ctx_deinit(ctx); 209 ecdsa_ecc_ctx_deinit(ctx); 193 ret = ecdsa_ecc_ctx_init(ctx, curve_id 210 ret = ecdsa_ecc_ctx_init(ctx, curve_id); 194 if (ret == 0) 211 if (ret == 0) 195 ctx->pub_key = ECC_POINT_INIT( 212 ctx->pub_key = ECC_POINT_INIT(ctx->x, ctx->y, 196 213 ctx->curve->g.ndigits); 197 return ret; 214 return ret; 198 } 215 } 199 216 200 /* 217 /* 201 * Set the public ECC key as defined by RFC548 !! 218 * Set the public key given the raw uncompressed key data from an X509 202 * Key". Only the uncompressed format is suppo !! 219 * certificate. The key data contain the concatenated X and Y coordinates of >> 220 * the public key. 203 */ 221 */ 204 static int ecdsa_set_pub_key(struct crypto_akc 222 static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen) 205 { 223 { 206 struct ecc_ctx *ctx = akcipher_tfm_ctx 224 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 207 unsigned int digitlen, ndigits; 225 unsigned int digitlen, ndigits; 208 const unsigned char *d = key; 226 const unsigned char *d = key; 209 int ret; 227 int ret; 210 228 211 ret = ecdsa_ecc_ctx_reset(ctx); 229 ret = ecdsa_ecc_ctx_reset(ctx); 212 if (ret < 0) 230 if (ret < 0) 213 return ret; 231 return ret; 214 232 215 if (keylen < 1 || ((keylen - 1) & 1) ! 233 if (keylen < 1 || ((keylen - 1) & 1) != 0) 216 return -EINVAL; 234 return -EINVAL; 217 /* we only accept uncompressed format 235 /* we only accept uncompressed format indicated by '4' */ 218 if (d[0] != 4) 236 if (d[0] != 4) 219 return -EINVAL; 237 return -EINVAL; 220 238 221 keylen--; 239 keylen--; 222 digitlen = keylen >> 1; 240 digitlen = keylen >> 1; 223 241 224 ndigits = DIV_ROUND_UP(digitlen, sizeo 242 ndigits = DIV_ROUND_UP(digitlen, sizeof(u64)); 225 if (ndigits != ctx->curve->g.ndigits) 243 if (ndigits != ctx->curve->g.ndigits) 226 return -EINVAL; 244 return -EINVAL; 227 245 228 d++; 246 d++; 229 247 230 ecc_digits_from_bytes(d, digitlen, ctx 248 ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits); 231 ecc_digits_from_bytes(&d[digitlen], di 249 ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits); 232 250 233 ret = ecc_is_pubkey_valid_full(ctx->cu 251 ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key); 234 252 235 ctx->pub_key_set = ret == 0; 253 ctx->pub_key_set = ret == 0; 236 254 237 return ret; 255 return ret; 238 } 256 } 239 257 240 static void ecdsa_exit_tfm(struct crypto_akcip 258 static void ecdsa_exit_tfm(struct crypto_akcipher *tfm) 241 { 259 { 242 struct ecc_ctx *ctx = akcipher_tfm_ctx 260 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 243 261 244 ecdsa_ecc_ctx_deinit(ctx); 262 ecdsa_ecc_ctx_deinit(ctx); 245 } 263 } 246 264 247 static unsigned int ecdsa_max_size(struct cryp 265 static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm) 248 { 266 { 249 struct ecc_ctx *ctx = akcipher_tfm_ctx 267 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 250 268 251 return DIV_ROUND_UP(ctx->curve->nbits, 269 return DIV_ROUND_UP(ctx->curve->nbits, 8); 252 } 270 } 253 271 254 static int ecdsa_nist_p521_init_tfm(struct cry 272 static int ecdsa_nist_p521_init_tfm(struct crypto_akcipher *tfm) 255 { 273 { 256 struct ecc_ctx *ctx = akcipher_tfm_ctx 274 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 257 275 258 return ecdsa_ecc_ctx_init(ctx, ECC_CUR 276 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P521); 259 } 277 } 260 278 261 static struct akcipher_alg ecdsa_nist_p521 = { 279 static struct akcipher_alg ecdsa_nist_p521 = { 262 .verify = ecdsa_verify, 280 .verify = ecdsa_verify, 263 .set_pub_key = ecdsa_set_pub_key, 281 .set_pub_key = ecdsa_set_pub_key, 264 .max_size = ecdsa_max_size, 282 .max_size = ecdsa_max_size, 265 .init = ecdsa_nist_p521_init_tfm, 283 .init = ecdsa_nist_p521_init_tfm, 266 .exit = ecdsa_exit_tfm, 284 .exit = ecdsa_exit_tfm, 267 .base = { 285 .base = { 268 .cra_name = "ecdsa-nist-p521", 286 .cra_name = "ecdsa-nist-p521", 269 .cra_driver_name = "ecdsa-nist 287 .cra_driver_name = "ecdsa-nist-p521-generic", 270 .cra_priority = 100, 288 .cra_priority = 100, 271 .cra_module = THIS_MODULE, 289 .cra_module = THIS_MODULE, 272 .cra_ctxsize = sizeof(struct e 290 .cra_ctxsize = sizeof(struct ecc_ctx), 273 }, 291 }, 274 }; 292 }; 275 293 276 static int ecdsa_nist_p384_init_tfm(struct cry 294 static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm) 277 { 295 { 278 struct ecc_ctx *ctx = akcipher_tfm_ctx 296 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 279 297 280 return ecdsa_ecc_ctx_init(ctx, ECC_CUR 298 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P384); 281 } 299 } 282 300 283 static struct akcipher_alg ecdsa_nist_p384 = { 301 static struct akcipher_alg ecdsa_nist_p384 = { 284 .verify = ecdsa_verify, 302 .verify = ecdsa_verify, 285 .set_pub_key = ecdsa_set_pub_key, 303 .set_pub_key = ecdsa_set_pub_key, 286 .max_size = ecdsa_max_size, 304 .max_size = ecdsa_max_size, 287 .init = ecdsa_nist_p384_init_tfm, 305 .init = ecdsa_nist_p384_init_tfm, 288 .exit = ecdsa_exit_tfm, 306 .exit = ecdsa_exit_tfm, 289 .base = { 307 .base = { 290 .cra_name = "ecdsa-nist-p384", 308 .cra_name = "ecdsa-nist-p384", 291 .cra_driver_name = "ecdsa-nist 309 .cra_driver_name = "ecdsa-nist-p384-generic", 292 .cra_priority = 100, 310 .cra_priority = 100, 293 .cra_module = THIS_MODULE, 311 .cra_module = THIS_MODULE, 294 .cra_ctxsize = sizeof(struct e 312 .cra_ctxsize = sizeof(struct ecc_ctx), 295 }, 313 }, 296 }; 314 }; 297 315 298 static int ecdsa_nist_p256_init_tfm(struct cry 316 static int ecdsa_nist_p256_init_tfm(struct crypto_akcipher *tfm) 299 { 317 { 300 struct ecc_ctx *ctx = akcipher_tfm_ctx 318 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 301 319 302 return ecdsa_ecc_ctx_init(ctx, ECC_CUR 320 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P256); 303 } 321 } 304 322 305 static struct akcipher_alg ecdsa_nist_p256 = { 323 static struct akcipher_alg ecdsa_nist_p256 = { 306 .verify = ecdsa_verify, 324 .verify = ecdsa_verify, 307 .set_pub_key = ecdsa_set_pub_key, 325 .set_pub_key = ecdsa_set_pub_key, 308 .max_size = ecdsa_max_size, 326 .max_size = ecdsa_max_size, 309 .init = ecdsa_nist_p256_init_tfm, 327 .init = ecdsa_nist_p256_init_tfm, 310 .exit = ecdsa_exit_tfm, 328 .exit = ecdsa_exit_tfm, 311 .base = { 329 .base = { 312 .cra_name = "ecdsa-nist-p256", 330 .cra_name = "ecdsa-nist-p256", 313 .cra_driver_name = "ecdsa-nist 331 .cra_driver_name = "ecdsa-nist-p256-generic", 314 .cra_priority = 100, 332 .cra_priority = 100, 315 .cra_module = THIS_MODULE, 333 .cra_module = THIS_MODULE, 316 .cra_ctxsize = sizeof(struct e 334 .cra_ctxsize = sizeof(struct ecc_ctx), 317 }, 335 }, 318 }; 336 }; 319 337 320 static int ecdsa_nist_p192_init_tfm(struct cry 338 static int ecdsa_nist_p192_init_tfm(struct crypto_akcipher *tfm) 321 { 339 { 322 struct ecc_ctx *ctx = akcipher_tfm_ctx 340 struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); 323 341 324 return ecdsa_ecc_ctx_init(ctx, ECC_CUR 342 return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P192); 325 } 343 } 326 344 327 static struct akcipher_alg ecdsa_nist_p192 = { 345 static struct akcipher_alg ecdsa_nist_p192 = { 328 .verify = ecdsa_verify, 346 .verify = ecdsa_verify, 329 .set_pub_key = ecdsa_set_pub_key, 347 .set_pub_key = ecdsa_set_pub_key, 330 .max_size = ecdsa_max_size, 348 .max_size = ecdsa_max_size, 331 .init = ecdsa_nist_p192_init_tfm, 349 .init = ecdsa_nist_p192_init_tfm, 332 .exit = ecdsa_exit_tfm, 350 .exit = ecdsa_exit_tfm, 333 .base = { 351 .base = { 334 .cra_name = "ecdsa-nist-p192", 352 .cra_name = "ecdsa-nist-p192", 335 .cra_driver_name = "ecdsa-nist 353 .cra_driver_name = "ecdsa-nist-p192-generic", 336 .cra_priority = 100, 354 .cra_priority = 100, 337 .cra_module = THIS_MODULE, 355 .cra_module = THIS_MODULE, 338 .cra_ctxsize = sizeof(struct e 356 .cra_ctxsize = sizeof(struct ecc_ctx), 339 }, 357 }, 340 }; 358 }; 341 static bool ecdsa_nist_p192_registered; 359 static bool ecdsa_nist_p192_registered; 342 360 343 static int __init ecdsa_init(void) 361 static int __init ecdsa_init(void) 344 { 362 { 345 int ret; 363 int ret; 346 364 347 /* NIST p192 may not be available in F 365 /* NIST p192 may not be available in FIPS mode */ 348 ret = crypto_register_akcipher(&ecdsa_ 366 ret = crypto_register_akcipher(&ecdsa_nist_p192); 349 ecdsa_nist_p192_registered = ret == 0; 367 ecdsa_nist_p192_registered = ret == 0; 350 368 351 ret = crypto_register_akcipher(&ecdsa_ 369 ret = crypto_register_akcipher(&ecdsa_nist_p256); 352 if (ret) 370 if (ret) 353 goto nist_p256_error; 371 goto nist_p256_error; 354 372 355 ret = crypto_register_akcipher(&ecdsa_ 373 ret = crypto_register_akcipher(&ecdsa_nist_p384); 356 if (ret) 374 if (ret) 357 goto nist_p384_error; 375 goto nist_p384_error; 358 376 359 ret = crypto_register_akcipher(&ecdsa_ 377 ret = crypto_register_akcipher(&ecdsa_nist_p521); 360 if (ret) 378 if (ret) 361 goto nist_p521_error; 379 goto nist_p521_error; 362 380 363 return 0; 381 return 0; 364 382 365 nist_p521_error: 383 nist_p521_error: 366 crypto_unregister_akcipher(&ecdsa_nist 384 crypto_unregister_akcipher(&ecdsa_nist_p384); 367 385 368 nist_p384_error: 386 nist_p384_error: 369 crypto_unregister_akcipher(&ecdsa_nist 387 crypto_unregister_akcipher(&ecdsa_nist_p256); 370 388 371 nist_p256_error: 389 nist_p256_error: 372 if (ecdsa_nist_p192_registered) 390 if (ecdsa_nist_p192_registered) 373 crypto_unregister_akcipher(&ec 391 crypto_unregister_akcipher(&ecdsa_nist_p192); 374 return ret; 392 return ret; 375 } 393 } 376 394 377 static void __exit ecdsa_exit(void) 395 static void __exit ecdsa_exit(void) 378 { 396 { 379 if (ecdsa_nist_p192_registered) 397 if (ecdsa_nist_p192_registered) 380 crypto_unregister_akcipher(&ec 398 crypto_unregister_akcipher(&ecdsa_nist_p192); 381 crypto_unregister_akcipher(&ecdsa_nist 399 crypto_unregister_akcipher(&ecdsa_nist_p256); 382 crypto_unregister_akcipher(&ecdsa_nist 400 crypto_unregister_akcipher(&ecdsa_nist_p384); 383 crypto_unregister_akcipher(&ecdsa_nist 401 crypto_unregister_akcipher(&ecdsa_nist_p521); 384 } 402 } 385 403 386 subsys_initcall(ecdsa_init); 404 subsys_initcall(ecdsa_init); 387 module_exit(ecdsa_exit); 405 module_exit(ecdsa_exit); 388 406 389 MODULE_LICENSE("GPL"); 407 MODULE_LICENSE("GPL"); 390 MODULE_AUTHOR("Stefan Berger <stefanb@linux.ib 408 MODULE_AUTHOR("Stefan Berger <stefanb@linux.ibm.com>"); 391 MODULE_DESCRIPTION("ECDSA generic algorithm"); 409 MODULE_DESCRIPTION("ECDSA generic algorithm"); 392 MODULE_ALIAS_CRYPTO("ecdsa-nist-p192"); 410 MODULE_ALIAS_CRYPTO("ecdsa-nist-p192"); 393 MODULE_ALIAS_CRYPTO("ecdsa-nist-p256"); 411 MODULE_ALIAS_CRYPTO("ecdsa-nist-p256"); 394 MODULE_ALIAS_CRYPTO("ecdsa-nist-p384"); 412 MODULE_ALIAS_CRYPTO("ecdsa-nist-p384"); 395 MODULE_ALIAS_CRYPTO("ecdsa-nist-p521"); 413 MODULE_ALIAS_CRYPTO("ecdsa-nist-p521"); 396 MODULE_ALIAS_CRYPTO("ecdsa-generic"); 414 MODULE_ALIAS_CRYPTO("ecdsa-generic"); 397 415
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.