summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/hcrypto/rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/heimdal/lib/hcrypto/rsa.c')
-rw-r--r--source4/heimdal/lib/hcrypto/rsa.c257
1 files changed, 201 insertions, 56 deletions
diff --git a/source4/heimdal/lib/hcrypto/rsa.c b/source4/heimdal/lib/hcrypto/rsa.c
index 9b9ecea674..a3fc0cd7ae 100644
--- a/source4/heimdal/lib/hcrypto/rsa.c
+++ b/source4/heimdal/lib/hcrypto/rsa.c
@@ -38,8 +38,12 @@
#include <krb5-types.h>
#include <rfc2459_asn1.h>
+#include <der.h>
+
#include <rsa.h>
+#include "common.h"
+
#include <roken.h>
/**
@@ -48,6 +52,22 @@
* RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
* Adleman) (published in 1977), patented expired in 21 September 2000.
*
+ *
+ * Speed for RSA in seconds
+ * no key blinding
+ * 1000 iteration,
+ * same rsa keys (1024 and 2048)
+ * operation performed each eteration sign, verify, encrypt, decrypt on a random bit pattern
+ *
+ * name 1024 2048 4098
+ * =================================
+ * gmp: 0.73 6.60 44.80
+ * tfm: 2.45 -- --
+ * ltm: 3.79 20.74 105.41 (default in hcrypto)
+ * openssl: 4.04 11.90 82.59
+ * cdsa: 15.89 102.89 721.40
+ * imath: 40.62 -- --
+ *
* See the library functions here: @ref hcrypto_rsa
*/
@@ -237,7 +257,7 @@ RSA_set_app_data(RSA *rsa, void *arg)
*/
void *
-RSA_get_app_data(RSA *rsa)
+RSA_get_app_data(const RSA *rsa)
{
return rsa->ex_data.sk;
}
@@ -278,7 +298,7 @@ RSA_check_key(const RSA *key)
return 0;
}
- if (ret == sizeof(inbuf) && memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
+ if (ret == sizeof(inbuf) && ct_memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
free(buffer);
return 1;
}
@@ -303,19 +323,136 @@ RSAFUNC(RSA_public_decrypt, (r)->meth->rsa_pub_dec(flen, f, t, r, p))
RSAFUNC(RSA_private_encrypt, (r)->meth->rsa_priv_enc(flen, f, t, r, p))
RSAFUNC(RSA_private_decrypt, (r)->meth->rsa_priv_dec(flen, f, t, r, p))
-/* XXX */
+static const heim_octet_string null_entry_oid = { 2, rk_UNCONST("\x05\x00") };
+
+static const unsigned sha1_oid_tree[] = { 1, 3, 14, 3, 2, 26 };
+static const AlgorithmIdentifier _signature_sha1_data = {
+ { 6, rk_UNCONST(sha1_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+static const unsigned sha256_oid_tree[] = { 2, 16, 840, 1, 101, 3, 4, 2, 1 };
+static const AlgorithmIdentifier _signature_sha256_data = {
+ { 9, rk_UNCONST(sha256_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+static const unsigned md5_oid_tree[] = { 1, 2, 840, 113549, 2, 5 };
+static const AlgorithmIdentifier _signature_md5_data = {
+ { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
+};
+
+
int
RSA_sign(int type, const unsigned char *from, unsigned int flen,
unsigned char *to, unsigned int *tlen, RSA *rsa)
{
- return -1;
+ if (rsa->meth->rsa_sign)
+ return rsa->meth->rsa_sign(type, from, flen, to, tlen, rsa);
+
+ if (rsa->meth->rsa_priv_enc) {
+ heim_octet_string indata;
+ DigestInfo di;
+ size_t size;
+ int ret;
+
+ memset(&di, 0, sizeof(di));
+
+ if (type == NID_sha1) {
+ di.digestAlgorithm = _signature_sha1_data;
+ } else if (type == NID_md5) {
+ di.digestAlgorithm = _signature_md5_data;
+ } else if (type == NID_sha256) {
+ di.digestAlgorithm = _signature_sha256_data;
+ } else
+ return -1;
+
+ di.digest.data = rk_UNCONST(from);
+ di.digest.length = flen;
+
+ ASN1_MALLOC_ENCODE(DigestInfo,
+ indata.data,
+ indata.length,
+ &di,
+ &size,
+ ret);
+ if (ret)
+ return ret;
+ if (indata.length != size)
+ abort();
+
+ ret = rsa->meth->rsa_priv_enc(indata.length, indata.data, to,
+ rsa, RSA_PKCS1_PADDING);
+ free(indata.data);
+ if (ret > 0) {
+ *tlen = ret;
+ ret = 1;
+ } else
+ ret = 0;
+
+ return ret;
+ }
+
+ return 0;
}
int
RSA_verify(int type, const unsigned char *from, unsigned int flen,
- unsigned char *to, unsigned int tlen, RSA *rsa)
+ unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
{
- return -1;
+ if (rsa->meth->rsa_verify)
+ return rsa->meth->rsa_verify(type, from, flen, sigbuf, siglen, rsa);
+
+ if (rsa->meth->rsa_pub_dec) {
+ const AlgorithmIdentifier *digest_alg;
+ void *data;
+ DigestInfo di;
+ size_t size;
+ int ret, ret2;
+
+ data = malloc(RSA_size(rsa));
+ if (data == NULL)
+ return -1;
+
+ memset(&di, 0, sizeof(di));
+
+ ret = rsa->meth->rsa_pub_dec(siglen, sigbuf, data, rsa, RSA_PKCS1_PADDING);
+ if (ret <= 0) {
+ free(data);
+ return -2;
+ }
+
+ ret2 = decode_DigestInfo(data, ret, &di, &size);
+ free(data);
+ if (ret2 != 0)
+ return -3;
+ if (ret != size) {
+ free_DigestInfo(&di);
+ return -4;
+ }
+
+ if (flen != di.digest.length || memcmp(di.digest.data, from, flen) != 0) {
+ free_DigestInfo(&di);
+ return -5;
+ }
+
+ if (type == NID_sha1) {
+ digest_alg = &_signature_sha1_data;
+ } else if (type == NID_md5) {
+ digest_alg = &_signature_md5_data;
+ } else if (type == NID_sha256) {
+ digest_alg = &_signature_sha256_data;
+ } else {
+ free_DigestInfo(&di);
+ return -1;
+ }
+
+ ret = der_heim_oid_cmp(&digest_alg->algorithm,
+ &di.digestAlgorithm.algorithm);
+ free_DigestInfo(&di);
+
+ if (ret != 0)
+ return 0;
+ return 1;
+ }
+
+ return 0;
}
/*
@@ -380,12 +517,11 @@ RSA_null_method(void)
return &rsa_null_method;
}
-extern const RSA_METHOD hc_rsa_imath_method;
-#ifdef HAVE_GMP
-static const RSA_METHOD *default_rsa_method = &hc_rsa_gmp_method;
-#else
-static const RSA_METHOD *default_rsa_method = &hc_rsa_imath_method;
-#endif
+extern const RSA_METHOD hc_rsa_gmp_method;
+extern const RSA_METHOD hc_rsa_tfm_method;
+extern const RSA_METHOD hc_rsa_ltm_method;
+static const RSA_METHOD *default_rsa_method = &hc_rsa_ltm_method;
+
const RSA_METHOD *
RSA_get_default_method(void)
@@ -403,32 +539,6 @@ RSA_set_default_method(const RSA_METHOD *meth)
*
*/
-static BIGNUM *
-heim_int2BN(const heim_integer *i)
-{
- BIGNUM *bn;
-
- bn = BN_bin2bn(i->data, i->length, NULL);
- if (bn)
- BN_set_negative(bn, i->negative);
- return bn;
-}
-
-static int
-bn2heim_int(BIGNUM *bn, heim_integer *integer)
-{
- integer->length = BN_num_bytes(bn);
- integer->data = malloc(integer->length);
- if (integer->data == NULL) {
- integer->length = 0;
- return ENOMEM;
- }
- BN_bn2bin(bn, integer->data);
- integer->negative = BN_is_negative(bn);
- return 0;
-}
-
-
RSA *
d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
{
@@ -451,14 +561,14 @@ d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
}
}
- k->n = heim_int2BN(&data.modulus);
- k->e = heim_int2BN(&data.publicExponent);
- k->d = heim_int2BN(&data.privateExponent);
- k->p = heim_int2BN(&data.prime1);
- k->q = heim_int2BN(&data.prime2);
- k->dmp1 = heim_int2BN(&data.exponent1);
- k->dmq1 = heim_int2BN(&data.exponent2);
- k->iqmp = heim_int2BN(&data.coefficient);
+ k->n = _hc_integer_to_BN(&data.modulus, NULL);
+ k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
+ k->d = _hc_integer_to_BN(&data.privateExponent, NULL);
+ k->p = _hc_integer_to_BN(&data.prime1, NULL);
+ k->q = _hc_integer_to_BN(&data.prime2, NULL);
+ k->dmp1 = _hc_integer_to_BN(&data.exponent1, NULL);
+ k->dmq1 = _hc_integer_to_BN(&data.exponent2, NULL);
+ k->iqmp = _hc_integer_to_BN(&data.coefficient, NULL);
free_RSAPrivateKey(&data);
if (k->n == NULL || k->e == NULL || k->d == NULL || k->p == NULL ||
@@ -485,14 +595,14 @@ i2d_RSAPrivateKey(RSA *rsa, unsigned char **pp)
memset(&data, 0, sizeof(data));
- ret = bn2heim_int(rsa->n, &data.modulus);
- ret |= bn2heim_int(rsa->e, &data.publicExponent);
- ret |= bn2heim_int(rsa->d, &data.privateExponent);
- ret |= bn2heim_int(rsa->p, &data.prime1);
- ret |= bn2heim_int(rsa->q, &data.prime2);
- ret |= bn2heim_int(rsa->dmp1, &data.exponent1);
- ret |= bn2heim_int(rsa->dmq1, &data.exponent2);
- ret |= bn2heim_int(rsa->iqmp, &data.coefficient);
+ ret = _hc_BN_to_integer(rsa->n, &data.modulus);
+ ret |= _hc_BN_to_integer(rsa->e, &data.publicExponent);
+ ret |= _hc_BN_to_integer(rsa->d, &data.privateExponent);
+ ret |= _hc_BN_to_integer(rsa->p, &data.prime1);
+ ret |= _hc_BN_to_integer(rsa->q, &data.prime2);
+ ret |= _hc_BN_to_integer(rsa->dmp1, &data.exponent1);
+ ret |= _hc_BN_to_integer(rsa->dmq1, &data.exponent2);
+ ret |= _hc_BN_to_integer(rsa->iqmp, &data.coefficient);
if (ret) {
free_RSAPrivateKey(&data);
return -1;
@@ -530,8 +640,8 @@ i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
memset(&data, 0, sizeof(data));
- if (bn2heim_int(rsa->n, &data.modulus) ||
- bn2heim_int(rsa->e, &data.publicExponent))
+ if (_hc_BN_to_integer(rsa->n, &data.modulus) ||
+ _hc_BN_to_integer(rsa->e, &data.publicExponent))
{
free_RSAPublicKey(&data);
return -1;
@@ -559,3 +669,38 @@ i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
return size;
}
+
+RSA *
+d2i_RSAPublicKey(RSA *rsa, const unsigned char **pp, size_t len)
+{
+ RSAPublicKey data;
+ RSA *k = rsa;
+ size_t size;
+ int ret;
+
+ ret = decode_RSAPublicKey(*pp, len, &data, &size);
+ if (ret)
+ return NULL;
+
+ *pp += size;
+
+ if (k == NULL) {
+ k = RSA_new();
+ if (k == NULL) {
+ free_RSAPublicKey(&data);
+ return NULL;
+ }
+ }
+
+ k->n = _hc_integer_to_BN(&data.modulus, NULL);
+ k->e = _hc_integer_to_BN(&data.publicExponent, NULL);
+
+ free_RSAPublicKey(&data);
+
+ if (k->n == NULL || k->e == NULL) {
+ RSA_free(k);
+ return NULL;
+ }
+
+ return k;
+}