summaryrefslogtreecommitdiffstats
path: root/crypto/asymmetric_keys
diff options
context:
space:
mode:
authorTadeusz Struk <tadeusz.struk@intel.com>2016-02-02 13:08:53 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2016-02-06 02:33:25 -0500
commit57f96bbab9d9fa89e79c30866e50aea61ffa7938 (patch)
treee4d5adac23a105660f809f26421dc78a52fb15a6 /crypto/asymmetric_keys
parentb31dde2a5cb1bf764282abf934266b7193c2bc7c (diff)
crypto: asymmetric_keys - convert public key and digsig asym to the akcipher api
This patch converts the module verification code to the new akcipher API. Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/asymmetric_keys')
-rw-r--r--crypto/asymmetric_keys/Kconfig2
-rw-r--r--crypto/asymmetric_keys/Makefile7
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c12
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c2
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c2
-rw-r--r--crypto/asymmetric_keys/public_key.c64
-rw-r--r--crypto/asymmetric_keys/public_key.h36
-rw-r--r--crypto/asymmetric_keys/rsa.c213
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c37
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c17
-rw-r--r--crypto/asymmetric_keys/x509_rsakey.asn14
11 files changed, 124 insertions, 272 deletions
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 4870f28403f5..905d745c2f85 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -22,7 +22,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
22 22
23config PUBLIC_KEY_ALGO_RSA 23config PUBLIC_KEY_ALGO_RSA
24 tristate "RSA public-key algorithm" 24 tristate "RSA public-key algorithm"
25 select MPILIB 25 select CRYPTO_RSA
26 help 26 help
27 This option enables support for the RSA algorithm (PKCS#1, RFC3447). 27 This option enables support for the RSA algorithm (PKCS#1, RFC3447).
28 28
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index cd1406f9b14a..b78a194ea014 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -16,21 +16,18 @@ obj-$(CONFIG_X509_CERTIFICATE_PARSER) += x509_key_parser.o
16x509_key_parser-y := \ 16x509_key_parser-y := \
17 x509-asn1.o \ 17 x509-asn1.o \
18 x509_akid-asn1.o \ 18 x509_akid-asn1.o \
19 x509_rsakey-asn1.o \
20 x509_cert_parser.o \ 19 x509_cert_parser.o \
21 x509_public_key.o 20 x509_public_key.o
22 21
23$(obj)/x509_cert_parser.o: \ 22$(obj)/x509_cert_parser.o: \
24 $(obj)/x509-asn1.h \ 23 $(obj)/x509-asn1.h \
25 $(obj)/x509_akid-asn1.h \ 24 $(obj)/x509_akid-asn1.h
26 $(obj)/x509_rsakey-asn1.h 25
27$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h 26$(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
28$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h 27$(obj)/x509_akid-asn1.o: $(obj)/x509_akid-asn1.c $(obj)/x509_akid-asn1.h
29$(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
30 28
31clean-files += x509-asn1.c x509-asn1.h 29clean-files += x509-asn1.c x509-asn1.h
32clean-files += x509_akid-asn1.c x509_akid-asn1.h 30clean-files += x509_akid-asn1.c x509_akid-asn1.h
33clean-files += x509_rsakey-asn1.c x509_rsakey-asn1.h
34 31
35# 32#
36# PKCS#7 message handling 33# PKCS#7 message handling
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 8f3056cd0399..3ef62dac9771 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -15,7 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/oid_registry.h> 17#include <linux/oid_registry.h>
18#include "public_key.h" 18#include <crypto/public_key.h>
19#include "pkcs7_parser.h" 19#include "pkcs7_parser.h"
20#include "pkcs7-asn1.h" 20#include "pkcs7-asn1.h"
21 21
@@ -44,7 +44,7 @@ struct pkcs7_parse_context {
44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo) 44static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
45{ 45{
46 if (sinfo) { 46 if (sinfo) {
47 mpi_free(sinfo->sig.mpi[0]); 47 kfree(sinfo->sig.s);
48 kfree(sinfo->sig.digest); 48 kfree(sinfo->sig.digest);
49 kfree(sinfo->signing_cert_id); 49 kfree(sinfo->signing_cert_id);
50 kfree(sinfo); 50 kfree(sinfo);
@@ -614,16 +614,14 @@ int pkcs7_sig_note_signature(void *context, size_t hdrlen,
614 const void *value, size_t vlen) 614 const void *value, size_t vlen)
615{ 615{
616 struct pkcs7_parse_context *ctx = context; 616 struct pkcs7_parse_context *ctx = context;
617 MPI mpi;
618 617
619 BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA); 618 BUG_ON(ctx->sinfo->sig.pkey_algo != PKEY_ALGO_RSA);
620 619
621 mpi = mpi_read_raw_data(value, vlen); 620 ctx->sinfo->sig.s = kmemdup(value, vlen, GFP_KERNEL);
622 if (!mpi) 621 if (!ctx->sinfo->sig.s)
623 return -ENOMEM; 622 return -ENOMEM;
624 623
625 ctx->sinfo->sig.mpi[0] = mpi; 624 ctx->sinfo->sig.s_size = vlen;
626 ctx->sinfo->sig.nr_mpi = 1;
627 return 0; 625 return 0;
628} 626}
629 627
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 90d6d47965b0..3bbdcc79a3d3 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -17,7 +17,7 @@
17#include <linux/asn1.h> 17#include <linux/asn1.h>
18#include <linux/key.h> 18#include <linux/key.h>
19#include <keys/asymmetric-type.h> 19#include <keys/asymmetric-type.h>
20#include "public_key.h" 20#include <crypto/public_key.h>
21#include "pkcs7_parser.h" 21#include "pkcs7_parser.h"
22 22
23/** 23/**
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index 325575caf6b4..f5db1378c096 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -16,7 +16,7 @@
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/asn1.h> 17#include <linux/asn1.h>
18#include <crypto/hash.h> 18#include <crypto/hash.h>
19#include "public_key.h" 19#include <crypto/public_key.h>
20#include "pkcs7_parser.h" 20#include "pkcs7_parser.h"
21 21
22/* 22/*
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 6db4c01c6503..b383629b9e62 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -18,24 +18,16 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <keys/asymmetric-subtype.h> 20#include <keys/asymmetric-subtype.h>
21#include "public_key.h" 21#include <crypto/public_key.h>
22 22
23MODULE_LICENSE("GPL"); 23MODULE_LICENSE("GPL");
24 24
25const char *const pkey_algo_name[PKEY_ALGO__LAST] = { 25const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
26 [PKEY_ALGO_DSA] = "DSA", 26 [PKEY_ALGO_DSA] = "dsa",
27 [PKEY_ALGO_RSA] = "RSA", 27 [PKEY_ALGO_RSA] = "rsa",
28}; 28};
29EXPORT_SYMBOL_GPL(pkey_algo_name); 29EXPORT_SYMBOL_GPL(pkey_algo_name);
30 30
31const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
32#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
33 defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
34 [PKEY_ALGO_RSA] = &RSA_public_key_algorithm,
35#endif
36};
37EXPORT_SYMBOL_GPL(pkey_algo);
38
39const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { 31const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
40 [PKEY_ID_PGP] = "PGP", 32 [PKEY_ID_PGP] = "PGP",
41 [PKEY_ID_X509] = "X509", 33 [PKEY_ID_X509] = "X509",
@@ -43,6 +35,12 @@ const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
43}; 35};
44EXPORT_SYMBOL_GPL(pkey_id_type_name); 36EXPORT_SYMBOL_GPL(pkey_id_type_name);
45 37
38static int (*alg_verify[PKEY_ALGO__LAST])(const struct public_key *pkey,
39 const struct public_key_signature *sig) = {
40 NULL,
41 rsa_verify_signature
42};
43
46/* 44/*
47 * Provide a part of a description of the key for /proc/keys. 45 * Provide a part of a description of the key for /proc/keys.
48 */ 46 */
@@ -53,7 +51,8 @@ static void public_key_describe(const struct key *asymmetric_key,
53 51
54 if (key) 52 if (key)
55 seq_printf(m, "%s.%s", 53 seq_printf(m, "%s.%s",
56 pkey_id_type_name[key->id_type], key->algo->name); 54 pkey_id_type_name[key->id_type],
55 pkey_algo_name[key->pkey_algo]);
57} 56}
58 57
59/* 58/*
@@ -62,50 +61,31 @@ static void public_key_describe(const struct key *asymmetric_key,
62void public_key_destroy(void *payload) 61void public_key_destroy(void *payload)
63{ 62{
64 struct public_key *key = payload; 63 struct public_key *key = payload;
65 int i;
66 64
67 if (key) { 65 if (key)
68 for (i = 0; i < ARRAY_SIZE(key->mpi); i++) 66 kfree(key->key);
69 mpi_free(key->mpi[i]); 67 kfree(key);
70 kfree(key);
71 }
72} 68}
73EXPORT_SYMBOL_GPL(public_key_destroy); 69EXPORT_SYMBOL_GPL(public_key_destroy);
74 70
75/* 71/*
76 * Verify a signature using a public key. 72 * Verify a signature using a public key.
77 */ 73 */
78int public_key_verify_signature(const struct public_key *pk, 74int public_key_verify_signature(const struct public_key *pkey,
79 const struct public_key_signature *sig) 75 const struct public_key_signature *sig)
80{ 76{
81 const struct public_key_algorithm *algo; 77 BUG_ON(!pkey);
82
83 BUG_ON(!pk);
84 BUG_ON(!pk->mpi[0]);
85 BUG_ON(!pk->mpi[1]);
86 BUG_ON(!sig); 78 BUG_ON(!sig);
87 BUG_ON(!sig->digest); 79 BUG_ON(!sig->digest);
88 BUG_ON(!sig->mpi[0]); 80 BUG_ON(!sig->s);
89
90 algo = pk->algo;
91 if (!algo) {
92 if (pk->pkey_algo >= PKEY_ALGO__LAST)
93 return -ENOPKG;
94 algo = pkey_algo[pk->pkey_algo];
95 if (!algo)
96 return -ENOPKG;
97 }
98 81
99 if (!algo->verify_signature) 82 if (pkey->pkey_algo >= PKEY_ALGO__LAST)
100 return -ENOTSUPP; 83 return -ENOPKG;
101 84
102 if (sig->nr_mpi != algo->n_sig_mpi) { 85 if (!alg_verify[pkey->pkey_algo])
103 pr_debug("Signature has %u MPI not %u\n", 86 return -ENOPKG;
104 sig->nr_mpi, algo->n_sig_mpi);
105 return -EINVAL;
106 }
107 87
108 return algo->verify_signature(pk, sig); 88 return alg_verify[pkey->pkey_algo](pkey, sig);
109} 89}
110EXPORT_SYMBOL_GPL(public_key_verify_signature); 90EXPORT_SYMBOL_GPL(public_key_verify_signature);
111 91
diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
deleted file mode 100644
index 5c37a22a0637..000000000000
--- a/crypto/asymmetric_keys/public_key.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/* Public key algorithm internals
2 *
3 * See Documentation/crypto/asymmetric-keys.txt
4 *
5 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
6 * Written by David Howells (dhowells@redhat.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public Licence
10 * as published by the Free Software Foundation; either version
11 * 2 of the Licence, or (at your option) any later version.
12 */
13
14#include <crypto/public_key.h>
15
16extern struct asymmetric_key_subtype public_key_subtype;
17
18/*
19 * Public key algorithm definition.
20 */
21struct public_key_algorithm {
22 const char *name;
23 u8 n_pub_mpi; /* Number of MPIs in public key */
24 u8 n_sec_mpi; /* Number of MPIs in secret key */
25 u8 n_sig_mpi; /* Number of MPIs in a signature */
26 int (*verify_signature)(const struct public_key *key,
27 const struct public_key_signature *sig);
28};
29
30extern const struct public_key_algorithm RSA_public_key_algorithm;
31
32/*
33 * public_key.c
34 */
35extern int public_key_verify_signature(const struct public_key *pk,
36 const struct public_key_signature *sig);
diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 508b57b77474..8b08ffcdb809 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -11,10 +11,10 @@
11 11
12#define pr_fmt(fmt) "RSA: "fmt 12#define pr_fmt(fmt) "RSA: "fmt
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
15#include <crypto/akcipher.h>
16#include <crypto/public_key.h>
16#include <crypto/algapi.h> 17#include <crypto/algapi.h>
17#include "public_key.h"
18 18
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20MODULE_DESCRIPTION("RSA Public Key Algorithm"); 20MODULE_DESCRIPTION("RSA Public Key Algorithm");
@@ -84,72 +84,10 @@ static const struct {
84#undef _ 84#undef _
85}; 85};
86 86
87/* 87struct rsa_completion {
88 * RSAVP1() function [RFC3447 sec 5.2.2] 88 struct completion completion;
89 */ 89 int err;
90static int RSAVP1(const struct public_key *key, MPI s, MPI *_m) 90};
91{
92 MPI m;
93 int ret;
94
95 /* (1) Validate 0 <= s < n */
96 if (mpi_cmp_ui(s, 0) < 0) {
97 kleave(" = -EBADMSG [s < 0]");
98 return -EBADMSG;
99 }
100 if (mpi_cmp(s, key->rsa.n) >= 0) {
101 kleave(" = -EBADMSG [s >= n]");
102 return -EBADMSG;
103 }
104
105 m = mpi_alloc(0);
106 if (!m)
107 return -ENOMEM;
108
109 /* (2) m = s^e mod n */
110 ret = mpi_powm(m, s, key->rsa.e, key->rsa.n);
111 if (ret < 0) {
112 mpi_free(m);
113 return ret;
114 }
115
116 *_m = m;
117 return 0;
118}
119
120/*
121 * Integer to Octet String conversion [RFC3447 sec 4.1]
122 */
123static int RSA_I2OSP(MPI x, size_t xLen, u8 **pX)
124{
125 unsigned X_size, x_size;
126 int X_sign;
127 u8 *X;
128
129 /* Make sure the string is the right length. The number should begin
130 * with { 0x00, 0x01, ... } so we have to account for 15 leading zero
131 * bits not being reported by MPI.
132 */
133 x_size = mpi_get_nbits(x);
134 pr_devel("size(x)=%u xLen*8=%zu\n", x_size, xLen * 8);
135 if (x_size != xLen * 8 - 15)
136 return -ERANGE;
137
138 X = mpi_get_buffer(x, &X_size, &X_sign);
139 if (!X)
140 return -ENOMEM;
141 if (X_sign < 0) {
142 kfree(X);
143 return -EBADMSG;
144 }
145 if (X_size != xLen - 1) {
146 kfree(X);
147 return -EBADMSG;
148 }
149
150 *pX = X;
151 return 0;
152}
153 91
154/* 92/*
155 * Perform the RSA signature verification. 93 * Perform the RSA signature verification.
@@ -160,7 +98,7 @@ static int RSA_I2OSP(MPI x, size_t xLen, u8 **pX)
160 * @asn1_template: The DigestInfo ASN.1 template 98 * @asn1_template: The DigestInfo ASN.1 template
161 * @asn1_size: Size of asm1_template[] 99 * @asn1_size: Size of asm1_template[]
162 */ 100 */
163static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size, 101static int rsa_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
164 const u8 *asn1_template, size_t asn1_size) 102 const u8 *asn1_template, size_t asn1_size)
165{ 103{
166 unsigned PS_end, T_offset, i; 104 unsigned PS_end, T_offset, i;
@@ -169,10 +107,10 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
169 107
170 if (k < 2 + 1 + asn1_size + hash_size) 108 if (k < 2 + 1 + asn1_size + hash_size)
171 return -EBADMSG; 109 return -EBADMSG;
172 110 /* Decode the EMSA-PKCS1-v1_5
173 /* Decode the EMSA-PKCS1-v1_5 */ 111 * note: leading zeros are stirpped by the RSA implementation */
174 if (EM[1] != 0x01) { 112 if (EM[0] != 0x01) {
175 kleave(" = -EBADMSG [EM[1] == %02u]", EM[1]); 113 kleave(" = -EBADMSG [EM[0] == %02u]", EM[0]);
176 return -EBADMSG; 114 return -EBADMSG;
177 } 115 }
178 116
@@ -183,7 +121,7 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
183 return -EBADMSG; 121 return -EBADMSG;
184 } 122 }
185 123
186 for (i = 2; i < PS_end; i++) { 124 for (i = 1; i < PS_end; i++) {
187 if (EM[i] != 0xff) { 125 if (EM[i] != 0xff) {
188 kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]); 126 kleave(" = -EBADMSG [EM[PS%x] == %02u]", i - 2, EM[i]);
189 return -EBADMSG; 127 return -EBADMSG;
@@ -204,75 +142,82 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
204 return 0; 142 return 0;
205} 143}
206 144
207/* 145static void public_key_verify_done(struct crypto_async_request *req, int err)
208 * Perform the verification step [RFC3447 sec 8.2.2].
209 */
210static int RSA_verify_signature(const struct public_key *key,
211 const struct public_key_signature *sig)
212{ 146{
213 size_t tsize; 147 struct rsa_completion *compl = req->data;
214 int ret;
215 148
216 /* Variables as per RFC3447 sec 8.2.2 */ 149 if (err == -EINPROGRESS)
217 const u8 *H = sig->digest; 150 return;
218 u8 *EM = NULL;
219 MPI m = NULL;
220 size_t k;
221 151
222 kenter(""); 152 compl->err = err;
223 153 complete(&compl->completion);
224 if (!RSA_ASN1_templates[sig->pkey_hash_algo].data) 154}
225 return -ENOTSUPP;
226
227 /* (1) Check the signature size against the public key modulus size */
228 k = mpi_get_nbits(key->rsa.n);
229 tsize = mpi_get_nbits(sig->rsa.s);
230 155
231 /* According to RFC 4880 sec 3.2, length of MPI is computed starting 156int rsa_verify_signature(const struct public_key *pkey,
232 * from most significant bit. So the RFC 3447 sec 8.2.2 size check 157 const struct public_key_signature *sig)
233 * must be relaxed to conform with shorter signatures - so we fail here 158{
234 * only if signature length is longer than modulus size. 159 struct crypto_akcipher *tfm;
235 */ 160 struct akcipher_request *req;
236 pr_devel("step 1: k=%zu size(S)=%zu\n", k, tsize); 161 struct rsa_completion compl;
237 if (k < tsize) { 162 struct scatterlist sig_sg, sg_out;
238 ret = -EBADMSG; 163 void *outbuf = NULL;
239 goto error; 164 unsigned int outlen = 0;
165 int ret = -ENOMEM;
166
167 tfm = crypto_alloc_akcipher("rsa", 0, 0);
168 if (IS_ERR(tfm))
169 goto error_out;
170
171 req = akcipher_request_alloc(tfm, GFP_KERNEL);
172 if (!req)
173 goto error_free_tfm;
174
175 ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen);
176 if (ret)
177 goto error_free_req;
178
179 ret = -EINVAL;
180 outlen = crypto_akcipher_maxsize(tfm);
181 if (!outlen)
182 goto error_free_req;
183
184 /* initlialzie out buf */
185 ret = -ENOMEM;
186 outbuf = kmalloc(outlen, GFP_KERNEL);
187 if (!outbuf)
188 goto error_free_req;
189
190 sg_init_one(&sig_sg, sig->s, sig->s_size);
191 sg_init_one(&sg_out, outbuf, outlen);
192 akcipher_request_set_crypt(req, &sig_sg, &sg_out, sig->s_size, outlen);
193 init_completion(&compl.completion);
194 akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
195 CRYPTO_TFM_REQ_MAY_SLEEP,
196 public_key_verify_done, &compl);
197
198 ret = crypto_akcipher_verify(req);
199 if (ret == -EINPROGRESS) {
200 wait_for_completion(&compl.completion);
201 ret = compl.err;
240 } 202 }
241 203
242 /* Round up and convert to octets */ 204 if (ret)
243 k = (k + 7) / 8; 205 goto error_free_req;
244 206
245 /* (2b) Apply the RSAVP1 verification primitive to the public key */ 207 /*
246 ret = RSAVP1(key, sig->rsa.s, &m); 208 * Output from the operation is an encoded message (EM) of
247 if (ret < 0) 209 * length k octets.
248 goto error;
249
250 /* (2c) Convert the message representative (m) to an encoded message
251 * (EM) of length k octets.
252 *
253 * NOTE! The leading zero byte is suppressed by MPI, so we pass a
254 * pointer to the _preceding_ byte to RSA_verify()!
255 */ 210 */
256 ret = RSA_I2OSP(m, k, &EM); 211 outlen = req->dst_len;
257 if (ret < 0) 212 ret = rsa_verify(sig->digest, outbuf, outlen, sig->digest_size,
258 goto error;
259
260 ret = RSA_verify(H, EM - 1, k, sig->digest_size,
261 RSA_ASN1_templates[sig->pkey_hash_algo].data, 213 RSA_ASN1_templates[sig->pkey_hash_algo].data,
262 RSA_ASN1_templates[sig->pkey_hash_algo].size); 214 RSA_ASN1_templates[sig->pkey_hash_algo].size);
263 215error_free_req:
264error: 216 akcipher_request_free(req);
265 kfree(EM); 217error_free_tfm:
266 mpi_free(m); 218 crypto_free_akcipher(tfm);
267 kleave(" = %d", ret); 219error_out:
220 kfree(outbuf);
268 return ret; 221 return ret;
269} 222}
270 223EXPORT_SYMBOL_GPL(rsa_verify_signature);
271const struct public_key_algorithm RSA_public_key_algorithm = {
272 .name = "RSA",
273 .n_pub_mpi = 2,
274 .n_sec_mpi = 3,
275 .n_sig_mpi = 1,
276 .verify_signature = RSA_verify_signature,
277};
278EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 021d39c0ba75..7502029e3385 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -15,11 +15,10 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/oid_registry.h> 17#include <linux/oid_registry.h>
18#include "public_key.h" 18#include <crypto/public_key.h>
19#include "x509_parser.h" 19#include "x509_parser.h"
20#include "x509-asn1.h" 20#include "x509-asn1.h"
21#include "x509_akid-asn1.h" 21#include "x509_akid-asn1.h"
22#include "x509_rsakey-asn1.h"
23 22
24struct x509_parse_context { 23struct x509_parse_context {
25 struct x509_certificate *cert; /* Certificate being constructed */ 24 struct x509_certificate *cert; /* Certificate being constructed */
@@ -56,7 +55,7 @@ void x509_free_certificate(struct x509_certificate *cert)
56 kfree(cert->akid_id); 55 kfree(cert->akid_id);
57 kfree(cert->akid_skid); 56 kfree(cert->akid_skid);
58 kfree(cert->sig.digest); 57 kfree(cert->sig.digest);
59 mpi_free(cert->sig.rsa.s); 58 kfree(cert->sig.s);
60 kfree(cert); 59 kfree(cert);
61 } 60 }
62} 61}
@@ -103,12 +102,12 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
103 } 102 }
104 } 103 }
105 104
106 /* Decode the public key */ 105 cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
107 ret = asn1_ber_decoder(&x509_rsakey_decoder, ctx, 106 if (!cert->pub->key)
108 ctx->key, ctx->key_size);
109 if (ret < 0)
110 goto error_decode; 107 goto error_decode;
111 108
109 cert->pub->keylen = ctx->key_size;
110
112 /* Generate cert issuer + serial number key ID */ 111 /* Generate cert issuer + serial number key ID */
113 kid = asymmetric_key_generate_id(cert->raw_serial, 112 kid = asymmetric_key_generate_id(cert->raw_serial,
114 cert->raw_serial_size, 113 cert->raw_serial_size,
@@ -124,6 +123,7 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
124 return cert; 123 return cert;
125 124
126error_decode: 125error_decode:
126 kfree(cert->pub->key);
127 kfree(ctx); 127 kfree(ctx);
128error_no_ctx: 128error_no_ctx:
129 x509_free_certificate(cert); 129 x509_free_certificate(cert);
@@ -404,29 +404,6 @@ int x509_extract_key_data(void *context, size_t hdrlen,
404 return 0; 404 return 0;
405} 405}
406 406
407/*
408 * Extract a RSA public key value
409 */
410int rsa_extract_mpi(void *context, size_t hdrlen,
411 unsigned char tag,
412 const void *value, size_t vlen)
413{
414 struct x509_parse_context *ctx = context;
415 MPI mpi;
416
417 if (ctx->nr_mpi >= ARRAY_SIZE(ctx->cert->pub->mpi)) {
418 pr_err("Too many public key MPIs in certificate\n");
419 return -EBADMSG;
420 }
421
422 mpi = mpi_read_raw_data(value, vlen);
423 if (!mpi)
424 return -ENOMEM;
425
426 ctx->cert->pub->mpi[ctx->nr_mpi++] = mpi;
427 return 0;
428}
429
430/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */ 407/* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
431#define SEQ_TAG_KEYID (ASN1_CONT << 6) 408#define SEQ_TAG_KEYID (ASN1_CONT << 6)
432 409
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 9e9e5a6a9ed6..7092d5cbb5d3 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -13,15 +13,11 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/err.h>
17#include <linux/mpi.h>
18#include <linux/asn1_decoder.h>
19#include <keys/asymmetric-subtype.h> 16#include <keys/asymmetric-subtype.h>
20#include <keys/asymmetric-parser.h> 17#include <keys/asymmetric-parser.h>
21#include <keys/system_keyring.h> 18#include <keys/system_keyring.h>
22#include <crypto/hash.h> 19#include <crypto/hash.h>
23#include "asymmetric_keys.h" 20#include "asymmetric_keys.h"
24#include "public_key.h"
25#include "x509_parser.h" 21#include "x509_parser.h"
26 22
27static bool use_builtin_keys; 23static bool use_builtin_keys;
@@ -167,13 +163,15 @@ int x509_get_sig_params(struct x509_certificate *cert)
167 163
168 if (cert->unsupported_crypto) 164 if (cert->unsupported_crypto)
169 return -ENOPKG; 165 return -ENOPKG;
170 if (cert->sig.rsa.s) 166 if (cert->sig.s)
171 return 0; 167 return 0;
172 168
173 cert->sig.rsa.s = mpi_read_raw_data(cert->raw_sig, cert->raw_sig_size); 169 cert->sig.s = kmemdup(cert->raw_sig, cert->raw_sig_size,
174 if (!cert->sig.rsa.s) 170 GFP_KERNEL);
171 if (!cert->sig.s)
175 return -ENOMEM; 172 return -ENOMEM;
176 cert->sig.nr_mpi = 1; 173
174 cert->sig.s_size = cert->raw_sig_size;
177 175
178 /* Allocate the hashing algorithm we're going to need and find out how 176 /* Allocate the hashing algorithm we're going to need and find out how
179 * big the hash operational data will be. 177 * big the hash operational data will be.
@@ -296,8 +294,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
296 if (cert->pub->pkey_algo >= PKEY_ALGO__LAST || 294 if (cert->pub->pkey_algo >= PKEY_ALGO__LAST ||
297 cert->sig.pkey_algo >= PKEY_ALGO__LAST || 295 cert->sig.pkey_algo >= PKEY_ALGO__LAST ||
298 cert->sig.pkey_hash_algo >= PKEY_HASH__LAST || 296 cert->sig.pkey_hash_algo >= PKEY_HASH__LAST ||
299 !pkey_algo[cert->pub->pkey_algo] ||
300 !pkey_algo[cert->sig.pkey_algo] ||
301 !hash_algo_name[cert->sig.pkey_hash_algo]) { 297 !hash_algo_name[cert->sig.pkey_hash_algo]) {
302 ret = -ENOPKG; 298 ret = -ENOPKG;
303 goto error_free_cert; 299 goto error_free_cert;
@@ -309,7 +305,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
309 pkey_algo_name[cert->sig.pkey_algo], 305 pkey_algo_name[cert->sig.pkey_algo],
310 hash_algo_name[cert->sig.pkey_hash_algo]); 306 hash_algo_name[cert->sig.pkey_hash_algo]);
311 307
312 cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
313 cert->pub->id_type = PKEY_ID_X509; 308 cert->pub->id_type = PKEY_ID_X509;
314 309
315 /* Check the signature on the key if it appears to be self-signed */ 310 /* Check the signature on the key if it appears to be self-signed */
diff --git a/crypto/asymmetric_keys/x509_rsakey.asn1 b/crypto/asymmetric_keys/x509_rsakey.asn1
deleted file mode 100644
index 4ec7cc6532c1..000000000000
--- a/crypto/asymmetric_keys/x509_rsakey.asn1
+++ /dev/null
@@ -1,4 +0,0 @@
1RSAPublicKey ::= SEQUENCE {
2 modulus INTEGER ({ rsa_extract_mpi }), -- n
3 publicExponent INTEGER ({ rsa_extract_mpi }) -- e
4 }