1 /* $NetBSD: rsa.c,v 1.1.1.2 2014/04/24 12:45:30 pettai Exp $ */
4 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 #include <krb5/krb5-types.h>
41 #include <krb5/rfc2459_asn1.h>
49 #include <krb5/roken.h>
52 * @page page_rsa RSA - public-key cryptography
54 * RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
55 * Adleman) (published in 1977), patented expired in 21 September 2000.
58 * Speed for RSA in seconds
61 * same rsa keys (1024 and 2048)
62 * operation performed each eteration sign, verify, encrypt, decrypt on a random bit pattern
65 * =================================
66 * gmp: 0.73 6.60 44.80
68 * ltm: 3.79 20.74 105.41 (default in hcrypto)
69 * openssl: 4.04 11.90 82.59
70 * cdsa: 15.89 102.89 721.40
73 * See the library functions here: @ref hcrypto_rsa
77 * Same as RSA_new_method() using NULL as engine.
79 * @return a newly allocated RSA object. Free with RSA_free().
81 * @ingroup hcrypto_rsa
87 return RSA_new_method(NULL
);
91 * Allocate a new RSA object using the engine, if NULL is specified as
92 * the engine, use the default RSA engine as returned by
93 * ENGINE_get_default_RSA().
95 * @param engine Specific what ENGINE RSA provider should be used.
97 * @return a newly allocated RSA object. Free with RSA_free().
99 * @ingroup hcrypto_rsa
103 RSA_new_method(ENGINE
*engine
)
107 rsa
= calloc(1, sizeof(*rsa
));
114 ENGINE_up_ref(engine
);
115 rsa
->engine
= engine
;
117 rsa
->engine
= ENGINE_get_default_RSA();
121 rsa
->meth
= ENGINE_get_RSA(rsa
->engine
);
122 if (rsa
->meth
== NULL
) {
123 ENGINE_finish(engine
);
129 if (rsa
->meth
== NULL
)
130 rsa
->meth
= rk_UNCONST(RSA_get_default_method());
132 (*rsa
->meth
->init
)(rsa
);
138 * Free an allocation RSA object.
140 * @param rsa the RSA object to free.
141 * @ingroup hcrypto_rsa
147 if (rsa
->references
<= 0)
150 if (--rsa
->references
> 0)
153 (*rsa
->meth
->finish
)(rsa
);
156 ENGINE_finish(rsa
->engine
);
158 #define free_if(f) if (f) { BN_free(f); }
169 memset(rsa
, 0, sizeof(*rsa
));
174 * Add an extra reference to the RSA object. The object should be free
175 * with RSA_free() to drop the reference.
177 * @param rsa the object to add reference counting too.
179 * @return the current reference count, can't safely be used except
180 * for debug printing.
182 * @ingroup hcrypto_rsa
188 return ++rsa
->references
;
192 * Return the RSA_METHOD used for this RSA object.
194 * @param rsa the object to get the method from.
196 * @return the method used for this RSA object.
198 * @ingroup hcrypto_rsa
202 RSA_get_method(const RSA
*rsa
)
208 * Set a new method for the RSA keypair.
210 * @param rsa rsa parameter.
211 * @param method the new method for the RSA parameter.
213 * @return 1 on success.
215 * @ingroup hcrypto_rsa
219 RSA_set_method(RSA
*rsa
, const RSA_METHOD
*method
)
221 (*rsa
->meth
->finish
)(rsa
);
224 ENGINE_finish(rsa
->engine
);
229 (*rsa
->meth
->init
)(rsa
);
234 * Set the application data for the RSA object.
236 * @param rsa the rsa object to set the parameter for
237 * @param arg the data object to store
239 * @return 1 on success.
241 * @ingroup hcrypto_rsa
245 RSA_set_app_data(RSA
*rsa
, void *arg
)
247 rsa
->ex_data
.sk
= arg
;
252 * Get the application data for the RSA object.
254 * @param rsa the rsa object to get the parameter for
256 * @return the data object
258 * @ingroup hcrypto_rsa
262 RSA_get_app_data(const RSA
*rsa
)
264 return rsa
->ex_data
.sk
;
268 RSA_check_key(const RSA
*key
)
270 static const unsigned char inbuf
[] = "hello, world!";
271 RSA
*rsa
= rk_UNCONST(key
);
276 * XXX I have no clue how to implement this w/o a bignum library.
277 * Well, when we have a RSA key pair, we can try to encrypt/sign
278 * and then decrypt/verify.
281 if ((rsa
->d
== NULL
|| rsa
->n
== NULL
) &&
282 (rsa
->p
== NULL
|| rsa
->q
|| rsa
->dmp1
== NULL
|| rsa
->dmq1
== NULL
|| rsa
->iqmp
== NULL
))
285 buffer
= malloc(RSA_size(rsa
));
289 ret
= RSA_private_encrypt(sizeof(inbuf
), inbuf
, buffer
,
290 rsa
, RSA_PKCS1_PADDING
);
296 ret
= RSA_public_decrypt(ret
, buffer
, buffer
,
297 rsa
, RSA_PKCS1_PADDING
);
303 if (ret
== sizeof(inbuf
) && ct_memcmp(buffer
, inbuf
, sizeof(inbuf
)) == 0) {
312 RSA_size(const RSA
*rsa
)
314 return BN_num_bytes(rsa
->n
);
317 #define RSAFUNC(name, body) \
319 name(int flen,const unsigned char* f, unsigned char* t, RSA* r, int p){\
323 RSAFUNC(RSA_public_encrypt
, (r
)->meth
->rsa_pub_enc(flen
, f
, t
, r
, p
))
324 RSAFUNC(RSA_public_decrypt
, (r
)->meth
->rsa_pub_dec(flen
, f
, t
, r
, p
))
325 RSAFUNC(RSA_private_encrypt
, (r
)->meth
->rsa_priv_enc(flen
, f
, t
, r
, p
))
326 RSAFUNC(RSA_private_decrypt
, (r
)->meth
->rsa_priv_dec(flen
, f
, t
, r
, p
))
328 static const heim_octet_string null_entry_oid
= { 2, rk_UNCONST("\x05\x00") };
330 static const unsigned sha1_oid_tree
[] = { 1, 3, 14, 3, 2, 26 };
331 static const AlgorithmIdentifier _signature_sha1_data
= {
332 { 6, rk_UNCONST(sha1_oid_tree
) }, rk_UNCONST(&null_entry_oid
)
334 static const unsigned sha256_oid_tree
[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
335 static const AlgorithmIdentifier _signature_sha256_data
= {
336 { 9, rk_UNCONST(sha256_oid_tree
) }, rk_UNCONST(&null_entry_oid
)
338 static const unsigned md5_oid_tree
[] = { 1, 2, 840, 113549, 2, 5 };
339 static const AlgorithmIdentifier _signature_md5_data
= {
340 { 6, rk_UNCONST(md5_oid_tree
) }, rk_UNCONST(&null_entry_oid
)
345 RSA_sign(int type
, const unsigned char *from
, unsigned int flen
,
346 unsigned char *to
, unsigned int *tlen
, RSA
*rsa
)
348 if (rsa
->meth
->rsa_sign
)
349 return rsa
->meth
->rsa_sign(type
, from
, flen
, to
, tlen
, rsa
);
351 if (rsa
->meth
->rsa_priv_enc
) {
352 heim_octet_string indata
;
357 memset(&di
, 0, sizeof(di
));
359 if (type
== NID_sha1
) {
360 di
.digestAlgorithm
= _signature_sha1_data
;
361 } else if (type
== NID_md5
) {
362 di
.digestAlgorithm
= _signature_md5_data
;
363 } else if (type
== NID_sha256
) {
364 di
.digestAlgorithm
= _signature_sha256_data
;
368 di
.digest
.data
= rk_UNCONST(from
);
369 di
.digest
.length
= flen
;
371 ASN1_MALLOC_ENCODE(DigestInfo
,
379 if (indata
.length
!= size
)
382 ret
= rsa
->meth
->rsa_priv_enc(indata
.length
, indata
.data
, to
,
383 rsa
, RSA_PKCS1_PADDING
);
398 RSA_verify(int type
, const unsigned char *from
, unsigned int flen
,
399 unsigned char *sigbuf
, unsigned int siglen
, RSA
*rsa
)
401 if (rsa
->meth
->rsa_verify
)
402 return rsa
->meth
->rsa_verify(type
, from
, flen
, sigbuf
, siglen
, rsa
);
404 if (rsa
->meth
->rsa_pub_dec
) {
405 const AlgorithmIdentifier
*digest_alg
;
411 data
= malloc(RSA_size(rsa
));
415 memset(&di
, 0, sizeof(di
));
417 ret
= rsa
->meth
->rsa_pub_dec(siglen
, sigbuf
, data
, rsa
, RSA_PKCS1_PADDING
);
423 ret2
= decode_DigestInfo(data
, ret
, &di
, &size
);
428 free_DigestInfo(&di
);
432 if (flen
!= di
.digest
.length
|| memcmp(di
.digest
.data
, from
, flen
) != 0) {
433 free_DigestInfo(&di
);
437 if (type
== NID_sha1
) {
438 digest_alg
= &_signature_sha1_data
;
439 } else if (type
== NID_md5
) {
440 digest_alg
= &_signature_md5_data
;
441 } else if (type
== NID_sha256
) {
442 digest_alg
= &_signature_sha256_data
;
444 free_DigestInfo(&di
);
448 ret
= der_heim_oid_cmp(&digest_alg
->algorithm
,
449 &di
.digestAlgorithm
.algorithm
);
450 free_DigestInfo(&di
);
461 * A NULL RSA_METHOD that returns failure for all operations. This is
462 * used as the default RSA method if we don't have any native
466 static RSAFUNC(null_rsa_public_encrypt
, -1)
467 static RSAFUNC(null_rsa_public_decrypt
, -1)
468 static RSAFUNC(null_rsa_private_encrypt
, -1)
469 static RSAFUNC(null_rsa_private_decrypt
, -1)
476 RSA_generate_key_ex(RSA
*r
, int bits
, BIGNUM
*e
, BN_GENCB
*cb
)
478 if (r
->meth
->rsa_keygen
)
479 return (*r
->meth
->rsa_keygen
)(r
, bits
, e
, cb
);
489 null_rsa_init(RSA
*rsa
)
495 null_rsa_finish(RSA
*rsa
)
500 static const RSA_METHOD rsa_null_method
= {
502 null_rsa_public_encrypt
,
503 null_rsa_public_decrypt
,
504 null_rsa_private_encrypt
,
505 null_rsa_private_decrypt
,
517 RSA_null_method(void)
519 return &rsa_null_method
;
522 extern const RSA_METHOD hc_rsa_gmp_method
;
523 extern const RSA_METHOD hc_rsa_tfm_method
;
524 extern const RSA_METHOD hc_rsa_ltm_method
;
525 static const RSA_METHOD
*default_rsa_method
= &hc_rsa_ltm_method
;
529 RSA_get_default_method(void)
531 return default_rsa_method
;
535 RSA_set_default_method(const RSA_METHOD
*meth
)
537 default_rsa_method
= meth
;
545 d2i_RSAPrivateKey(RSA
*rsa
, const unsigned char **pp
, size_t len
)
552 ret
= decode_RSAPrivateKey(*pp
, len
, &data
, &size
);
561 free_RSAPrivateKey(&data
);
566 k
->n
= _hc_integer_to_BN(&data
.modulus
, NULL
);
567 k
->e
= _hc_integer_to_BN(&data
.publicExponent
, NULL
);
568 k
->d
= _hc_integer_to_BN(&data
.privateExponent
, NULL
);
569 k
->p
= _hc_integer_to_BN(&data
.prime1
, NULL
);
570 k
->q
= _hc_integer_to_BN(&data
.prime2
, NULL
);
571 k
->dmp1
= _hc_integer_to_BN(&data
.exponent1
, NULL
);
572 k
->dmq1
= _hc_integer_to_BN(&data
.exponent2
, NULL
);
573 k
->iqmp
= _hc_integer_to_BN(&data
.coefficient
, NULL
);
574 free_RSAPrivateKey(&data
);
576 if (k
->n
== NULL
|| k
->e
== NULL
|| k
->d
== NULL
|| k
->p
== NULL
||
577 k
->q
== NULL
|| k
->dmp1
== NULL
|| k
->dmq1
== NULL
|| k
->iqmp
== NULL
)
587 i2d_RSAPrivateKey(RSA
*rsa
, unsigned char **pp
)
593 if (rsa
->n
== NULL
|| rsa
->e
== NULL
|| rsa
->d
== NULL
|| rsa
->p
== NULL
||
594 rsa
->q
== NULL
|| rsa
->dmp1
== NULL
|| rsa
->dmq1
== NULL
||
598 memset(&data
, 0, sizeof(data
));
600 ret
= _hc_BN_to_integer(rsa
->n
, &data
.modulus
);
601 ret
|= _hc_BN_to_integer(rsa
->e
, &data
.publicExponent
);
602 ret
|= _hc_BN_to_integer(rsa
->d
, &data
.privateExponent
);
603 ret
|= _hc_BN_to_integer(rsa
->p
, &data
.prime1
);
604 ret
|= _hc_BN_to_integer(rsa
->q
, &data
.prime2
);
605 ret
|= _hc_BN_to_integer(rsa
->dmp1
, &data
.exponent1
);
606 ret
|= _hc_BN_to_integer(rsa
->dmq1
, &data
.exponent2
);
607 ret
|= _hc_BN_to_integer(rsa
->iqmp
, &data
.coefficient
);
609 free_RSAPrivateKey(&data
);
614 size
= length_RSAPrivateKey(&data
);
615 free_RSAPrivateKey(&data
);
620 ASN1_MALLOC_ENCODE(RSAPrivateKey
, p
, len
, &data
, &size
, ret
);
621 free_RSAPrivateKey(&data
);
627 memcpy(*pp
, p
, size
);
637 i2d_RSAPublicKey(RSA
*rsa
, unsigned char **pp
)
643 memset(&data
, 0, sizeof(data
));
645 if (_hc_BN_to_integer(rsa
->n
, &data
.modulus
) ||
646 _hc_BN_to_integer(rsa
->e
, &data
.publicExponent
))
648 free_RSAPublicKey(&data
);
653 size
= length_RSAPublicKey(&data
);
654 free_RSAPublicKey(&data
);
659 ASN1_MALLOC_ENCODE(RSAPublicKey
, p
, len
, &data
, &size
, ret
);
660 free_RSAPublicKey(&data
);
666 memcpy(*pp
, p
, size
);
676 d2i_RSAPublicKey(RSA
*rsa
, const unsigned char **pp
, size_t len
)
683 ret
= decode_RSAPublicKey(*pp
, len
, &data
, &size
);
692 free_RSAPublicKey(&data
);
697 k
->n
= _hc_integer_to_BN(&data
.modulus
, NULL
);
698 k
->e
= _hc_integer_to_BN(&data
.publicExponent
, NULL
);
700 free_RSAPublicKey(&data
);
702 if (k
->n
== NULL
|| k
->e
== NULL
) {