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.
24 struct crypto_rsa_key
{
25 int private_key
; /* whether private key is set */
26 struct bignum
*n
; /* modulus (p * q) */
27 struct bignum
*e
; /* public exponent */
28 /* The following parameters are available only if private_key is set */
29 struct bignum
*d
; /* private exponent */
30 struct bignum
*p
; /* prime p (factor of n) */
31 struct bignum
*q
; /* prime q (factor of n) */
32 struct bignum
*dmp1
; /* d mod (p - 1); CRT exponent */
33 struct bignum
*dmq1
; /* d mod (q - 1); CRT exponent */
34 struct bignum
*iqmp
; /* 1 / q mod p; CRT coefficient */
38 static const u8
* crypto_rsa_parse_integer(const u8
*pos
, const u8
*end
,
46 if (asn1_get_next(pos
, end
- pos
, &hdr
) < 0 ||
47 hdr
.class != ASN1_CLASS_UNIVERSAL
|| hdr
.tag
!= ASN1_TAG_INTEGER
) {
48 wpa_printf(MSG_DEBUG
, "RSA: Expected INTEGER - found class %d "
49 "tag 0x%x", hdr
.class, hdr
.tag
);
53 if (bignum_set_unsigned_bin(num
, hdr
.payload
, hdr
.length
) < 0) {
54 wpa_printf(MSG_DEBUG
, "RSA: Failed to parse INTEGER");
58 return hdr
.payload
+ hdr
.length
;
63 * crypto_rsa_import_public_key - Import an RSA public key
64 * @buf: Key buffer (DER encoded RSA public key)
65 * @len: Key buffer length in bytes
66 * Returns: Pointer to the public key or %NULL on failure
68 struct crypto_rsa_key
*
69 crypto_rsa_import_public_key(const u8
*buf
, size_t len
)
71 struct crypto_rsa_key
*key
;
75 key
= os_zalloc(sizeof(*key
));
79 key
->n
= bignum_init();
80 key
->e
= bignum_init();
81 if (key
->n
== NULL
|| key
->e
== NULL
) {
88 * RSAPublicKey ::= SEQUENCE {
89 * modulus INTEGER, -- n
90 * publicExponent INTEGER -- e
94 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
95 hdr
.class != ASN1_CLASS_UNIVERSAL
||
96 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
97 wpa_printf(MSG_DEBUG
, "RSA: Expected SEQUENCE "
98 "(public key) - found class %d tag 0x%x",
103 end
= pos
+ hdr
.length
;
105 pos
= crypto_rsa_parse_integer(pos
, end
, key
->n
);
106 pos
= crypto_rsa_parse_integer(pos
, end
, key
->e
);
112 wpa_hexdump(MSG_DEBUG
,
113 "RSA: Extra data in public key SEQUENCE",
121 crypto_rsa_free(key
);
127 * crypto_rsa_import_private_key - Import an RSA private key
128 * @buf: Key buffer (DER encoded RSA private key)
129 * @len: Key buffer length in bytes
130 * Returns: Pointer to the private key or %NULL on failure
132 struct crypto_rsa_key
*
133 crypto_rsa_import_private_key(const u8
*buf
, size_t len
)
135 struct crypto_rsa_key
*key
;
140 key
= os_zalloc(sizeof(*key
));
144 key
->private_key
= 1;
146 key
->n
= bignum_init();
147 key
->e
= bignum_init();
148 key
->d
= bignum_init();
149 key
->p
= bignum_init();
150 key
->q
= bignum_init();
151 key
->dmp1
= bignum_init();
152 key
->dmq1
= bignum_init();
153 key
->iqmp
= bignum_init();
155 if (key
->n
== NULL
|| key
->e
== NULL
|| key
->d
== NULL
||
156 key
->p
== NULL
|| key
->q
== NULL
|| key
->dmp1
== NULL
||
157 key
->dmq1
== NULL
|| key
->iqmp
== NULL
) {
158 crypto_rsa_free(key
);
164 * RSAPrivateKey ::= SEQUENCE {
166 * modulus INTEGER, -- n
167 * publicExponent INTEGER, -- e
168 * privateExponent INTEGER, -- d
169 * prime1 INTEGER, -- p
170 * prime2 INTEGER, -- q
171 * exponent1 INTEGER, -- d mod (p-1)
172 * exponent2 INTEGER, -- d mod (q-1)
173 * coefficient INTEGER -- (inverse of q) mod p
176 * Version ::= INTEGER -- shall be 0 for this version of the standard
178 if (asn1_get_next(buf
, len
, &hdr
) < 0 ||
179 hdr
.class != ASN1_CLASS_UNIVERSAL
||
180 hdr
.tag
!= ASN1_TAG_SEQUENCE
) {
181 wpa_printf(MSG_DEBUG
, "RSA: Expected SEQUENCE "
182 "(public key) - found class %d tag 0x%x",
187 end
= pos
+ hdr
.length
;
189 zero
= bignum_init();
192 pos
= crypto_rsa_parse_integer(pos
, end
, zero
);
193 if (pos
== NULL
|| bignum_cmp_d(zero
, 0) != 0) {
194 wpa_printf(MSG_DEBUG
, "RSA: Expected zero INTEGER in the "
195 "beginning of private key; not found");
201 pos
= crypto_rsa_parse_integer(pos
, end
, key
->n
);
202 pos
= crypto_rsa_parse_integer(pos
, end
, key
->e
);
203 pos
= crypto_rsa_parse_integer(pos
, end
, key
->d
);
204 pos
= crypto_rsa_parse_integer(pos
, end
, key
->p
);
205 pos
= crypto_rsa_parse_integer(pos
, end
, key
->q
);
206 pos
= crypto_rsa_parse_integer(pos
, end
, key
->dmp1
);
207 pos
= crypto_rsa_parse_integer(pos
, end
, key
->dmq1
);
208 pos
= crypto_rsa_parse_integer(pos
, end
, key
->iqmp
);
214 wpa_hexdump(MSG_DEBUG
,
215 "RSA: Extra data in public key SEQUENCE",
223 crypto_rsa_free(key
);
229 * crypto_rsa_get_modulus_len - Get the modulus length of the RSA key
231 * Returns: Modulus length of the key
233 size_t crypto_rsa_get_modulus_len(struct crypto_rsa_key
*key
)
235 return bignum_get_unsigned_bin_len(key
->n
);
240 * crypto_rsa_exptmod - RSA modular exponentiation
242 * @inlen: Input data length
243 * @out: Buffer for output data
244 * @outlen: Maximum size of the output buffer and used size on success
246 * @use_private: 1 = Use RSA private key, 0 = Use RSA public key
247 * Returns: 0 on success, -1 on failure
249 int crypto_rsa_exptmod(const u8
*in
, size_t inlen
, u8
*out
, size_t *outlen
,
250 struct crypto_rsa_key
*key
, int use_private
)
252 struct bignum
*tmp
, *a
= NULL
, *b
= NULL
;
256 if (use_private
&& !key
->private_key
)
263 if (bignum_set_unsigned_bin(tmp
, in
, inlen
) < 0)
265 if (bignum_cmp(key
->n
, tmp
) < 0) {
266 /* Too large input value for the RSA key modulus */
272 * Decrypt (or sign) using Chinese remainer theorem to speed
273 * up calculation. This is equivalent to tmp = tmp^d mod n
274 * (which would require more CPU to calculate directly).
276 * dmp1 = (1/e) mod (p-1)
277 * dmq1 = (1/e) mod (q-1)
278 * iqmp = (1/q) mod p, where p > q
281 * h = q^-1 (m1 - m2) mod p
286 if (a
== NULL
|| b
== NULL
)
289 /* a = tmp^dmp1 mod p */
290 if (bignum_exptmod(tmp
, key
->dmp1
, key
->p
, a
) < 0)
293 /* b = tmp^dmq1 mod q */
294 if (bignum_exptmod(tmp
, key
->dmq1
, key
->q
, b
) < 0)
297 /* tmp = (a - b) * (1/q mod p) (mod p) */
298 if (bignum_sub(a
, b
, tmp
) < 0 ||
299 bignum_mulmod(tmp
, key
->iqmp
, key
->p
, tmp
) < 0)
302 /* tmp = b + q * tmp */
303 if (bignum_mul(tmp
, key
->q
, tmp
) < 0 ||
304 bignum_add(tmp
, b
, tmp
) < 0)
307 /* Encrypt (or verify signature) */
308 /* tmp = tmp^e mod N */
309 if (bignum_exptmod(tmp
, key
->e
, key
->n
, tmp
) < 0)
313 modlen
= crypto_rsa_get_modulus_len(key
);
314 if (modlen
> *outlen
) {
319 if (bignum_get_unsigned_bin_len(tmp
) > modlen
)
320 goto error
; /* should never happen */
323 os_memset(out
, 0, modlen
);
324 if (bignum_get_unsigned_bin(
326 (modlen
- bignum_get_unsigned_bin_len(tmp
)), NULL
) < 0)
340 * crypto_rsa_free - Free RSA key
341 * @key: RSA key to be freed
343 * This function frees an RSA key imported with either
344 * crypto_rsa_import_public_key() or crypto_rsa_import_private_key().
346 void crypto_rsa_free(struct crypto_rsa_key
*key
)
349 bignum_deinit(key
->n
);
350 bignum_deinit(key
->e
);
351 bignum_deinit(key
->d
);
352 bignum_deinit(key
->p
);
353 bignum_deinit(key
->q
);
354 bignum_deinit(key
->dmp1
);
355 bignum_deinit(key
->dmq1
);
356 bignum_deinit(key
->iqmp
);