3 * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
23 struct crypto_rsa_key
{
24 int private_key
; /* whether private key is set */
25 struct bignum
*n
; /* modulus (p * q) */
26 struct bignum
*e
; /* public exponent */
27 /* The following parameters are available only if private_key is set */
28 struct bignum
*d
; /* private exponent */
29 struct bignum
*p
; /* prime p (factor of n) */
30 struct bignum
*q
; /* prime q (factor of n) */
31 struct bignum
*dmp1
; /* d mod (p - 1); CRT exponent */
32 struct bignum
*dmq1
; /* d mod (q - 1); CRT exponent */
33 struct bignum
*iqmp
; /* 1 / q mod p; CRT coefficient */
37 static const u8
* crypto_rsa_parse_integer(const u8
*pos
, const u8
*end
,
45 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
46 hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_INTEGER
) {
47 wpa_printf(MSG_DEBUG
, "RSA: Expected INTEGER - found class %d "
48 "tag 0x%x", hdr
.class, hdr
.tag
);
52 if (bignum_set_unsigned_bin(num
, hdr
.payload
, hdr
.length
) < 0) {
53 wpa_printf(MSG_DEBUG
, "RSA: Failed to parse INTEGER");
57 return hdr
.payload
+ hdr
.length
;
62 * crypto_rsa_import_public_key - Import an RSA public key
63 * @buf: Key buffer (DER encoded RSA public key)
64 * @len: Key buffer length in bytes
65 * Returns: Pointer to the public key or %NULL on failure
67 struct crypto_rsa_key
*
68 crypto_rsa_import_public_key(const u8
*buf
, size_t len
)
70 struct crypto_rsa_key
*key
;
74 key
= os_zalloc(sizeof(*key
));
78 key
->n
= bignum_init();
79 key
->e
= bignum_init();
80 if (key
->n
== NULL
|| key
->e
== NULL
) {
87 * RSAPublicKey ::= SEQUENCE {
88 * modulus INTEGER, -- n
89 * publicExponent INTEGER -- e
93 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
94 hdr
.class != ASN1_CLASS_UNIVERSAL
||
95 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
96 wpa_printf(MSG_DEBUG
, "RSA: Expected SEQUENCE "
97 "(public key) - found class %d tag 0x%x",
102 end
= pos
+ hdr
.length
;
104 pos
= crypto_rsa_parse_integer(pos
, end
, key
->n
);
105 pos
= crypto_rsa_parse_integer(pos
, end
, key
->e
);
111 wpa_hexdump(MSG_DEBUG
,
112 "RSA: Extra data in public key SEQUENCE",
120 crypto_rsa_free(key
);
126 * crypto_rsa_import_private_key - Import an RSA private key
127 * @buf: Key buffer (DER encoded RSA private key)
128 * @len: Key buffer length in bytes
129 * Returns: Pointer to the private key or %NULL on failure
131 struct crypto_rsa_key
*
132 crypto_rsa_import_private_key(const u8
*buf
, size_t len
)
134 struct crypto_rsa_key
*key
;
139 key
= os_zalloc(sizeof(*key
));
143 key
->private_key
= 1;
145 key
->n
= bignum_init();
146 key
->e
= bignum_init();
147 key
->d
= bignum_init();
148 key
->p
= bignum_init();
149 key
->q
= bignum_init();
150 key
->dmp1
= bignum_init();
151 key
->dmq1
= bignum_init();
152 key
->iqmp
= bignum_init();
154 if (key
->n
== NULL
|| key
->e
== NULL
|| key
->d
== NULL
||
155 key
->p
== NULL
|| key
->q
== NULL
|| key
->dmp1
== NULL
||
156 key
->dmq1
== NULL
|| key
->iqmp
== NULL
) {
157 crypto_rsa_free(key
);
163 * RSAPrivateKey ::= SEQUENCE {
165 * modulus INTEGER, -- n
166 * publicExponent INTEGER, -- e
167 * privateExponent INTEGER, -- d
168 * prime1 INTEGER, -- p
169 * prime2 INTEGER, -- q
170 * exponent1 INTEGER, -- d mod (p-1)
171 * exponent2 INTEGER, -- d mod (q-1)
172 * coefficient INTEGER -- (inverse of q) mod p
175 * Version ::= INTEGER -- shall be 0 for this version of the standard
177 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
178 hdr
.class != ASN1_CLASS_UNIVERSAL
||
179 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
180 wpa_printf(MSG_DEBUG
, "RSA: Expected SEQUENCE "
181 "(public key) - found class %d tag 0x%x",
186 end
= pos
+ hdr
.length
;
188 zero
= bignum_init();
191 pos
= crypto_rsa_parse_integer(pos
, end
, zero
);
192 if (pos
== NULL
|| bignum_cmp_d(zero
, 0) != 0) {
193 wpa_printf(MSG_DEBUG
, "RSA: Expected zero INTEGER in the "
194 "beginning of private key; not found");
200 pos
= crypto_rsa_parse_integer(pos
, end
, key
->n
);
201 pos
= crypto_rsa_parse_integer(pos
, end
, key
->e
);
202 pos
= crypto_rsa_parse_integer(pos
, end
, key
->d
);
203 pos
= crypto_rsa_parse_integer(pos
, end
, key
->p
);
204 pos
= crypto_rsa_parse_integer(pos
, end
, key
->q
);
205 pos
= crypto_rsa_parse_integer(pos
, end
, key
->dmp1
);
206 pos
= crypto_rsa_parse_integer(pos
, end
, key
->dmq1
);
207 pos
= crypto_rsa_parse_integer(pos
, end
, key
->iqmp
);
213 wpa_hexdump(MSG_DEBUG
,
214 "RSA: Extra data in public key SEQUENCE",
222 crypto_rsa_free(key
);
228 * crypto_rsa_get_modulus_len - Get the modulus length of the RSA key
230 * Returns: Modulus length of the key
232 size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key
*key
)
234 return bignum_get_unsigned_bin_len(key
->n
);
239 * crypto_rsa_exptmod - RSA modular exponentiation
241 * @inlen: Input data length
242 * @out: Buffer for output data
243 * @outlen: Maximum size of the output buffer and used size on success
245 * @use_private: 1 = Use RSA private key, 0 = Use RSA public key
246 * Returns: 0 on success, -1 on failure
248 int crypto_rsa_exptmod(const u8
*in
, size_t inlen
, u8
*out
, size_t *outlen
,
249 struct crypto_rsa_key
*key
, int use_private
)
251 struct bignum
*tmp
, *a
= NULL
, *b
= NULL
;
255 if (use_private
&& !key
->private_key
)
262 if (bignum_set_unsigned_bin(tmp
, in
, inlen
) < 0)
264 if (bignum_cmp(key
->n
, tmp
) < 0) {
265 /* Too large input value for the RSA key modulus */
271 * Decrypt (or sign) using Chinese remainer theorem to speed
272 * up calculation. This is equivalent to tmp = tmp^d mod n
273 * (which would require more CPU to calculate directly).
275 * dmp1 = (1/e) mod (p-1)
276 * dmq1 = (1/e) mod (q-1)
277 * iqmp = (1/q) mod p, where p > q
280 * h = q^-1 (m1 - m2) mod p
285 if (a
== NULL
|| b
== NULL
)
288 /* a = tmp^dmp1 mod p */
289 if (bignum_exptmod(tmp
, key
->dmp1
, key
->p
, a
) < 0)
292 /* b = tmp^dmq1 mod q */
293 if (bignum_exptmod(tmp
, key
->dmq1
, key
->q
, b
) < 0)
296 /* tmp = (a - b) * (1/q mod p) (mod p) */
297 if (bignum_sub(a
, b
, tmp
) < 0 ||
298 bignum_mulmod(tmp
, key
->iqmp
, key
->p
, tmp
) < 0)
301 /* tmp = b + q * tmp */
302 if (bignum_mul(tmp
, key
->q
, tmp
) < 0 ||
303 bignum_add(tmp
, b
, tmp
) < 0)
306 /* Encrypt (or verify signature) */
307 /* tmp = tmp^e mod N */
308 if (bignum_exptmod(tmp
, key
->e
, key
->n
, tmp
) < 0)
312 modlen
= crypto_rsa_get_modulus_len(key
);
313 if (modlen
> *outlen
) {
318 if (bignum_get_unsigned_bin_len(tmp
) > modlen
)
319 goto error
; /* should never happen */
322 os_memset(out
, 0, modlen
);
323 if (bignum_get_unsigned_bin(
325 (modlen
- bignum_get_unsigned_bin_len(tmp
)), NULL
) < 0)
339 * crypto_rsa_free - Free RSA key
340 * @key: RSA key to be freed
342 * This function frees an RSA key imported with either
343 * crypto_rsa_import_public_key() or crypto_rsa_import_private_key().
345 void crypto_rsa_free(struct crypto_rsa_key
*key
)
348 bignum_deinit(key
->n
);
349 bignum_deinit(key
->e
);
350 bignum_deinit(key
->d
);
351 bignum_deinit(key
->p
);
352 bignum_deinit(key
->q
);
353 bignum_deinit(key
->dmp1
);
354 bignum_deinit(key
->dmq1
);
355 bignum_deinit(key
->iqmp
);