Browse Source

Merge pull request #302 from libtom/fix/pr/301

re-work PK crypto im- & export
Steffen Jaeckel 8 years ago
parent
commit
01a61e64ef

+ 0 - 1
README.md

@@ -48,7 +48,6 @@ The following list is a small part of the available, but the most often required
 | ---- | -------- |
 | ---- | -------- |
 | `LTC_NO_TEST` | Remove all algorithm self-tests from the library |
 | `LTC_NO_TEST` | Remove all algorithm self-tests from the library |
 | `LTC_NO_FILE` | Remove all API functions requiring a pre-defined `FILE` data-type (mostly useful for embedded targets) |
 | `LTC_NO_FILE` | Remove all API functions requiring a pre-defined `FILE` data-type (mostly useful for embedded targets) |
-| `MAX_RSA_SIZE` | Per default set to `4096`, if you need support for importing or generating bigger RSA keys, change this at compile-time. |
 | `GMP_DESC` | enable [gmp](https://gmplib.org/) as MPI provider *\*1* |
 | `GMP_DESC` | enable [gmp](https://gmplib.org/) as MPI provider *\*1* |
 | `LTM_DESC` | enable [libtommath](http://www.libtom.net/) as MPI provider *\*1* |
 | `LTM_DESC` | enable [libtommath](http://www.libtom.net/) as MPI provider *\*1* |
 | `TFM_DESC` | enable [tomsfastmath](http://www.libtom.net/) as MPI provider *\*1* *\*2* |
 | `TFM_DESC` | enable [tomsfastmath](http://www.libtom.net/) as MPI provider *\*1* *\*2* |

+ 1 - 1
demos/demo_dynamic.py

@@ -150,7 +150,7 @@ if SHOW_SELECTED_CONSTANTS:
         b'ENDIAN_LITTLE',
         b'ENDIAN_LITTLE',
         b'ENDIAN_64BITWORD',
         b'ENDIAN_64BITWORD',
         b'PK_PUBLIC',
         b'PK_PUBLIC',
-        b'MAX_RSA_SIZE',
+        b'LTC_MILLER_RABIN_REPS',
         b'CTR_COUNTER_BIG_ENDIAN',
         b'CTR_COUNTER_BIG_ENDIAN',
     ]
     ]
     for name in names:
     for name in names:

+ 1 - 0
makefile_include.mk

@@ -76,6 +76,7 @@ endif
 LTC_CFLAGS += -Wno-type-limits
 LTC_CFLAGS += -Wno-type-limits
 
 
 ifdef LTC_DEBUG
 ifdef LTC_DEBUG
+$(info Debug build)
 # compile for DEBUGGING (required for ccmalloc checking!!!)
 # compile for DEBUGGING (required for ccmalloc checking!!!)
 LTC_CFLAGS += -g3 -DLTC_NO_ASM
 LTC_CFLAGS += -g3 -DLTC_NO_ASM
 ifneq (,$(strip $(LTC_DEBUG)))
 ifneq (,$(strip $(LTC_DEBUG)))

+ 0 - 24
src/headers/tomcrypt_custom.h

@@ -425,30 +425,6 @@
 #define LTC_ECC_TIMING_RESISTANT
 #define LTC_ECC_TIMING_RESISTANT
 #endif
 #endif
 
 
-/* define these PK sizes out of LTC_NO_PK
- * to have them always defined
- */
-#if defined(LTC_MRSA)
-/* Min and Max RSA key sizes (in bits) */
-#ifndef MIN_RSA_SIZE
-#define MIN_RSA_SIZE 1024
-#endif
-#ifndef MAX_RSA_SIZE
-#define MAX_RSA_SIZE 4096
-#endif
-#endif
-
-/* in cases where you want ASN.1/DER functionality, but no
- * RSA, you can define this externally if 1024 is not enough
- */
-#if defined(LTC_MRSA)
-#define LTC_DER_MAX_PUBKEY_SIZE MAX_RSA_SIZE
-#elif !defined(LTC_DER_MAX_PUBKEY_SIZE)
-/* this includes DSA */
-#define LTC_DER_MAX_PUBKEY_SIZE 1024
-#endif
-
-
 /* PKCS #1 (RSA) and #5 (Password Handling) stuff */
 /* PKCS #1 (RSA) and #5 (Password Handling) stuff */
 #ifndef LTC_NO_PKCS
 #ifndef LTC_NO_PKCS
 
 

+ 0 - 3
src/misc/crypt/crypt.c

@@ -399,9 +399,6 @@ const char *crypt_build_settings =
 #if defined(LTC_DER)
 #if defined(LTC_DER)
     " DER "
     " DER "
 #endif
 #endif
-#if defined(LTC_DER_MAX_PUBKEY_SIZE)
-    " " NAME_VALUE(LTC_DER_MAX_PUBKEY_SIZE) " "
-#endif
 #if defined(LTC_PKCS_1)
 #if defined(LTC_PKCS_1)
     " PKCS#1 "
     " PKCS#1 "
 #endif
 #endif

+ 0 - 5
src/misc/crypt/crypt_constants.c

@@ -77,8 +77,6 @@ static const crypt_constant _crypt_constants[] = {
 
 
 #ifdef LTC_MRSA
 #ifdef LTC_MRSA
     {"LTC_MRSA", 1},
     {"LTC_MRSA", 1},
-    _C_STRINGIFY(MIN_RSA_SIZE),
-    _C_STRINGIFY(MAX_RSA_SIZE),
 #else
 #else
     {"LTC_MRSA", 0},
     {"LTC_MRSA", 0},
 #endif
 #endif
@@ -107,9 +105,6 @@ static const crypt_constant _crypt_constants[] = {
     {"LTC_MDSA", 0},
     {"LTC_MDSA", 0},
 #endif
 #endif
 
 
-#ifdef LTC_DER_MAX_PUBKEY_SIZE
-    _C_STRINGIFY(LTC_DER_MAX_PUBKEY_SIZE),
-#endif
 #ifdef LTC_MILLER_RABIN_REPS
 #ifdef LTC_MILLER_RABIN_REPS
     _C_STRINGIFY(LTC_MILLER_RABIN_REPS),
     _C_STRINGIFY(LTC_MILLER_RABIN_REPS),
 #endif
 #endif

+ 9 - 6
src/pk/asn1/der/bit/der_decode_raw_bit_string.c

@@ -17,6 +17,7 @@
 #ifdef LTC_DER
 #ifdef LTC_DER
 
 
 #define SETBIT(v, n)    (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
 #define SETBIT(v, n)    (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
+#define CLRBIT(v, n)    (v=((unsigned char)(v) & ~(1U << (unsigned char)(n))))
 
 
 /**
 /**
   Store a BIT STRING
   Store a BIT STRING
@@ -84,12 +85,14 @@ int der_decode_raw_bit_string(const unsigned char *in,  unsigned long inlen,
 
 
    /* decode/store the bits */
    /* decode/store the bits */
    for (y = 0; y < blen; y++) {
    for (y = 0; y < blen; y++) {
-       if (in[x] & (1 << (7 - (y & 7)))) {
-          SETBIT(out[y/8], 7-(y%8));
-       }
-       if ((y & 7) == 7) {
-          ++x;
-       }
+      if (in[x] & (1 << (7 - (y & 7)))) {
+         SETBIT(out[y/8], 7-(y%8));
+      } else {
+         CLRBIT(out[y/8], 7-(y%8));
+      }
+      if ((y & 7) == 7) {
+         ++x;
+      }
    }
    }
 
 
    /* we done */
    /* we done */

+ 6 - 6
src/pk/asn1/der/bit/der_encode_raw_bit_string.c

@@ -21,7 +21,7 @@
 /**
 /**
   Store a BIT STRING
   Store a BIT STRING
   @param in       The array of bits to store (8 per char)
   @param in       The array of bits to store (8 per char)
-  @param inlen    The number of bits tostore
+  @param inlen    The number of bits to store
   @param out      [out] The destination for the DER encoded BIT STRING
   @param out      [out] The destination for the DER encoded BIT STRING
   @param outlen   [in/out] The max size and resulting size of the DER BIT STRING
   @param outlen   [in/out] The max size and resulting size of the DER BIT STRING
   @return CRYPT_OK if successful
   @return CRYPT_OK if successful
@@ -68,11 +68,11 @@ int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
 
 
    /* store the bits in big endian format */
    /* store the bits in big endian format */
    for (y = buf = 0; y < inlen; y++) {
    for (y = buf = 0; y < inlen; y++) {
-        buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
-       if ((y & 7) == 7) {
-          out[x++] = buf;
-          buf      = 0;
-       }
+      buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
+      if ((y & 7) == 7) {
+         out[x++] = buf;
+         buf      = 0;
+      }
    }
    }
    /* store last byte */
    /* store last byte */
    if (inlen & 7) {
    if (inlen & 7) {

+ 2 - 2
src/pk/asn1/der/sequence/der_decode_subject_public_key_info.c

@@ -58,7 +58,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
    }
    }
 
 
    /* see if the OpenSSL DER format RSA public key will work */
    /* see if the OpenSSL DER format RSA public key will work */
-   tmpbuf = XCALLOC(1, LTC_DER_MAX_PUBKEY_SIZE*8);
+   tmpbuf = XCALLOC(1, inlen);
    if (tmpbuf == NULL) {
    if (tmpbuf == NULL) {
        err = CRYPT_MEM;
        err = CRYPT_MEM;
        goto LBL_ERR;
        goto LBL_ERR;
@@ -72,7 +72,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in
     * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet
     * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet
     */
     */
    LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
    LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2);
-   LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, LTC_DER_MAX_PUBKEY_SIZE*8);
+   LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U);
 
 
    err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
    err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
    if (err != CRYPT_OK) {
    if (err != CRYPT_OK) {

+ 1 - 1
src/pk/asn1/der/sequence/der_encode_subject_public_key_info.c

@@ -58,7 +58,7 @@ int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen
 
 
    return der_encode_sequence_multi(out, outlen,
    return der_encode_sequence_multi(out, outlen,
         LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
         LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
-        LTC_ASN1_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key,
+        LTC_ASN1_RAW_BIT_STRING, public_key_len*8U, public_key,
         LTC_ASN1_EOL,     0UL, NULL);
         LTC_ASN1_EOL,     0UL, NULL);
 
 
 }
 }

+ 1 - 1
src/pk/dsa/dsa_import.c

@@ -90,7 +90,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
        key->type = PK_PRIVATE;
        key->type = PK_PRIVATE;
    } else { /* public */
    } else { /* public */
       ltc_asn1_list params[3];
       ltc_asn1_list params[3];
-      unsigned long tmpbuf_len = LTC_DER_MAX_PUBKEY_SIZE*8;
+      unsigned long tmpbuf_len = inlen;
 
 
       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);

+ 1 - 1
src/pk/rsa/rsa_import.c

@@ -40,7 +40,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    }
    }
 
 
    /* see if the OpenSSL DER format RSA public key will work */
    /* see if the OpenSSL DER format RSA public key will work */
-   tmpbuf_len = MAX_RSA_SIZE * 8;
+   tmpbuf_len = inlen;
    tmpbuf = XCALLOC(1, tmpbuf_len);
    tmpbuf = XCALLOC(1, tmpbuf_len);
    if (tmpbuf == NULL) {
    if (tmpbuf == NULL) {
        err = CRYPT_MEM;
        err = CRYPT_MEM;

+ 1 - 1
src/pk/rsa/rsa_import_x509.c

@@ -39,7 +39,7 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key)
       return err;
       return err;
    }
    }
 
 
-   tmpbuf_len = MAX_RSA_SIZE * 8;
+   tmpbuf_len = inlen;
    tmpbuf = XCALLOC(1, tmpbuf_len);
    tmpbuf = XCALLOC(1, tmpbuf_len);
    if (tmpbuf == NULL) {
    if (tmpbuf == NULL) {
        err = CRYPT_MEM;
        err = CRYPT_MEM;

+ 1 - 4
src/pk/rsa/rsa_make_key.c

@@ -31,10 +31,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 
 
    LTC_ARGCHK(ltc_mp.name != NULL);
    LTC_ARGCHK(ltc_mp.name != NULL);
    LTC_ARGCHK(key         != NULL);
    LTC_ARGCHK(key         != NULL);
-
-   if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
-      return CRYPT_INVALID_KEYSIZE;
-   }
+   LTC_ARGCHK(size        > 0);
 
 
    if ((e < 3) || ((e & 1) == 0)) {
    if ((e < 3) || ((e & 1) == 0)) {
       return CRYPT_INVALID_ARG;
       return CRYPT_INVALID_ARG;

+ 2 - 2
tests/der_test.c

@@ -239,8 +239,8 @@ SEQUENCE(3 elem)
 static void _der_tests_print_flexi(ltc_asn1_list* l, unsigned int level)
 static void _der_tests_print_flexi(ltc_asn1_list* l, unsigned int level)
 {
 {
   char buf[1024];
   char buf[1024];
-  char* name = NULL;
-  char* text = NULL;
+  const char* name = NULL;
+  const char* text = NULL;
   ltc_asn1_list* ostring = NULL;
   ltc_asn1_list* ostring = NULL;
   unsigned int n;
   unsigned int n;
 
 

+ 60 - 0
tests/rsa_test.c

@@ -285,6 +285,64 @@ static int rsa_compat_test(void)
    return 0;
    return 0;
 }
 }
 
 
+static int _rsa_key_cmp(const int should_type, const rsa_key *should, const rsa_key *is)
+{
+   if(should_type != is->type)
+      return CRYPT_ERROR;
+   if(should_type == PK_PRIVATE) {
+      if(mp_cmp(should->q, is->q) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+      if(mp_cmp(should->p, is->p) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+      if(mp_cmp(should->qP, is->qP) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+      if(mp_cmp(should->dP, is->dP) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+      if(mp_cmp(should->dQ, is->dQ) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+      if(mp_cmp(should->d, is->d) != LTC_MP_EQ)
+         return CRYPT_ERROR;
+   }
+   if(mp_cmp(should->N, is->N) != LTC_MP_EQ)
+      return CRYPT_ERROR;
+   if(mp_cmp(should->e, is->e) != LTC_MP_EQ)
+      return CRYPT_ERROR;
+   return CRYPT_OK;
+}
+
+static int _rsa_issue_301(int prng_idx)
+{
+   rsa_key       key, key_in;
+   unsigned char buf[4096];
+   unsigned long len;
+
+   DO(rsa_make_key(&yarrow_prng, prng_idx, sizeof(buf)/8, 65537, &key));
+
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+   DO(rsa_import(buf, len, &key_in));
+
+   DO(_rsa_key_cmp(PK_PRIVATE, &key, &key_in));
+   rsa_free(&key_in);
+
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+   DO(rsa_import(buf, len, &key_in));
+
+   DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in));
+   rsa_free(&key_in);
+
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key));
+   DO(rsa_import(buf, len, &key_in));
+
+   DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in));
+   rsa_free(&key_in);
+
+   rsa_free(&key);
+   return CRYPT_OK;
+}
+
 int rsa_test(void)
 int rsa_test(void)
 {
 {
    unsigned char in[1024], out[1024], tmp[3072];
    unsigned char in[1024], out[1024], tmp[3072];
@@ -308,6 +366,8 @@ int rsa_test(void)
       return 1;
       return 1;
    }
    }
 
 
+   DO(_rsa_issue_301(prng_idx));
+
    /* make 10 random key */
    /* make 10 random key */
    for (cnt = 0; cnt < 10; cnt++) {
    for (cnt = 0; cnt < 10; cnt++) {
       DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key));
       DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key));