diff options
| author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-09-06 17:20:33 +0200 |
|---|---|---|
| committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-09-06 17:26:58 +0200 |
| commit | e6177630198eb1eea2def0374fae1196da0e40ec (patch) | |
| tree | 704951804609999fb6ef7a956b04921b9f84c320 /libtomcrypt/pk/rsa | |
| parent | 943f9ab50c110133a5cd1118b5b19cb09301168f (diff) | |
| download | cryptodev-linux-e6177630198eb1eea2def0374fae1196da0e40ec.tar.gz cryptodev-linux-e6177630198eb1eea2def0374fae1196da0e40ec.tar.xz cryptodev-linux-e6177630198eb1eea2def0374fae1196da0e40ec.zip | |
Run Lindent on libtom(*)
Diffstat (limited to 'libtomcrypt/pk/rsa')
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_decrypt_key.c | 133 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_encrypt_key.c | 97 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_export.c | 101 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_exptmod.c | 247 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_free.c | 9 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_import.c | 196 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_make_key.c | 186 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_sign_hash.c | 182 | ||||
| -rw-r--r-- | libtomcrypt/pk/rsa/rsa_verify_hash.c | 256 |
9 files changed, 756 insertions, 651 deletions
diff --git a/libtomcrypt/pk/rsa/rsa_decrypt_key.c b/libtomcrypt/pk/rsa/rsa_decrypt_key.c index 813a765..36573be 100644 --- a/libtomcrypt/pk/rsa/rsa_decrypt_key.c +++ b/libtomcrypt/pk/rsa/rsa_decrypt_key.c @@ -11,7 +11,6 @@ #include "tomcrypt.h" #include "ncr-int.h" - /** @file rsa_decrypt_key.c RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange @@ -33,71 +32,75 @@ @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ -int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - const struct algo_properties_st *hash, int padding, - int *stat, rsa_key *key) +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + const struct algo_properties_st *hash, int padding, + int *stat, rsa_key * key) { - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - unsigned char *tmp; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(stat != NULL); - - /* default to invalid */ - *stat = 0; - - /* valid padding? */ - - if ((padding != LTC_LTC_PKCS_1_V1_5) && - (padding != LTC_LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_LTC_PKCS_1_OAEP) { - /* valid hash ? */ - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits( (&key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size( (&key->N)); - if (modulus_bytelen != inlen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate ram */ - tmp = XMALLOC(inlen); - if (tmp == NULL) { - return CRYPT_MEM; - } - - /* rsa decode the packet */ - x = inlen; - if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { - XFREE(tmp); - return err; - } - - if (padding == LTC_LTC_PKCS_1_OAEP) { - /* now OAEP decode the packet */ - err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash, - out, outlen, stat); - } else { - /* now LTC_PKCS #1 v1.5 depad the packet */ - err = pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); - } - - XFREE(tmp); - return err; + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmp; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(stat != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* valid hash ? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((&key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((&key->N)); + if (modulus_bytelen != inlen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate ram */ + tmp = XMALLOC(inlen); + if (tmp == NULL) { + return CRYPT_MEM; + } + + /* rsa decode the packet */ + x = inlen; + if ((err = + rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { + XFREE(tmp); + return err; + } + + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* now OAEP decode the packet */ + err = + pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, + modulus_bitlen, hash, out, outlen, stat); + } else { + /* now LTC_PKCS #1 v1.5 depad the packet */ + err = + pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, + modulus_bitlen, out, outlen, stat); + } + + XFREE(tmp); + return err; } #endif /* LTC_MRSA */ diff --git a/libtomcrypt/pk/rsa/rsa_encrypt_key.c b/libtomcrypt/pk/rsa/rsa_encrypt_key.c index 8d3f2db..9367015 100644 --- a/libtomcrypt/pk/rsa/rsa_encrypt_key.c +++ b/libtomcrypt/pk/rsa/rsa_encrypt_key.c @@ -31,62 +31,63 @@ @param key The RSA key to encrypt to @return CRYPT_OK if successful */ -int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - const unsigned char *lparam, unsigned long lparamlen, - const struct algo_properties_st *hash, int padding, rsa_key *key) +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + const struct algo_properties_st *hash, int padding, + rsa_key * key) { - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); - /* valid padding? */ - if ((padding != LTC_LTC_PKCS_1_V1_5) && - (padding != LTC_LTC_PKCS_1_OAEP)) { - return CRYPT_PK_INVALID_PADDING; - } + /* valid padding? */ + if ((padding != LTC_LTC_PKCS_1_V1_5) && + (padding != LTC_LTC_PKCS_1_OAEP)) { + return CRYPT_PK_INVALID_PADDING; + } - if (padding == LTC_LTC_PKCS_1_OAEP) { - /* valid hash? */ - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - } + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* valid hash? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + } - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits( (&key->N)); + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((&key->N)); - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size( (&key->N)); - if (modulus_bytelen > *outlen) { - *outlen = modulus_bytelen; - return CRYPT_BUFFER_OVERFLOW; - } + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((&key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } - if (padding == LTC_LTC_PKCS_1_OAEP) { - /* OAEP pad the key */ - x = *outlen; - if ((err = pkcs_1_oaep_encode(in, inlen, lparam, - lparamlen, modulus_bitlen, hash, - out, &x)) != CRYPT_OK) { - return err; - } - } else { - /* LTC_PKCS #1 v1.5 pad the key */ - x = *outlen; - if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_LTC_PKCS_1_EME, - modulus_bitlen, - out, &x)) != CRYPT_OK) { - return err; - } - } + if (padding == LTC_LTC_PKCS_1_OAEP) { + /* OAEP pad the key */ + x = *outlen; + if ((err = pkcs_1_oaep_encode(in, inlen, lparam, + lparamlen, modulus_bitlen, hash, + out, &x)) != CRYPT_OK) { + return err; + } + } else { + /* LTC_PKCS #1 v1.5 pad the key */ + x = *outlen; + if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_LTC_PKCS_1_EME, + modulus_bitlen, + out, &x)) != CRYPT_OK) { + return err; + } + } - /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */ - return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key); + /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */ + return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key); } #endif /* LTC_MRSA */ diff --git a/libtomcrypt/pk/rsa/rsa_export.c b/libtomcrypt/pk/rsa/rsa_export.c index 21f859c..483af19 100644 --- a/libtomcrypt/pk/rsa/rsa_export.c +++ b/libtomcrypt/pk/rsa/rsa_export.c @@ -14,7 +14,7 @@ /** @file rsa_export.c Export RSA LTC_PKCS keys, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -25,59 +25,64 @@ @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) @param key The RSA key to export @return CRYPT_OK if successful -*/ -int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) +*/ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, + rsa_key * key) { - unsigned long zero=0; - int err; - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); + unsigned long zero = 0; + int err; + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); - /* type valid? */ - if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { - return CRYPT_PK_INVALID_TYPE; - } + /* type valid? */ + if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { + return CRYPT_PK_INVALID_TYPE; + } - if (type == PK_PRIVATE) { - /* private key */ - /* output is - Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p - */ - return der_encode_sequence_multi(out, outlen, - LTC_ASN1_SHORT_INTEGER, 1UL, &zero, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_INTEGER, 1UL, &key->d, - LTC_ASN1_INTEGER, 1UL, &key->p, - LTC_ASN1_INTEGER, 1UL, &key->q, - LTC_ASN1_INTEGER, 1UL, &key->dP, - LTC_ASN1_INTEGER, 1UL, &key->dQ, - LTC_ASN1_INTEGER, 1UL, &key->qP, - LTC_ASN1_EOL, 0UL, NULL); - } else { - unsigned long tmplen = (mp_count_bits(&key->N)/8)*2+8; - unsigned char* tmp = XMALLOC(tmplen); - - if (tmp == NULL) { - return CRYPT_MEM; - } + if (type == PK_PRIVATE) { + /* private key */ + /* output is + Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p + */ + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, + &zero, LTC_ASN1_INTEGER, 1UL, + &key->N, LTC_ASN1_INTEGER, 1UL, + &key->e, LTC_ASN1_INTEGER, 1UL, + &key->d, LTC_ASN1_INTEGER, 1UL, + &key->p, LTC_ASN1_INTEGER, 1UL, + &key->q, LTC_ASN1_INTEGER, 1UL, + &key->dP, LTC_ASN1_INTEGER, + 1UL, &key->dQ, + LTC_ASN1_INTEGER, 1UL, + &key->qP, LTC_ASN1_EOL, 0UL, + NULL); + } else { + unsigned long tmplen = (mp_count_bits(&key->N) / 8) * 2 + 8; + unsigned char *tmp = XMALLOC(tmplen); - err = der_encode_sequence_multi(tmp, &tmplen, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_EOL, 0UL, NULL); - if (err != CRYPT_OK) { - goto error; - } + if (tmp == NULL) { + return CRYPT_MEM; + } + + err = der_encode_sequence_multi(tmp, &tmplen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, &key->e, + LTC_ASN1_EOL, 0UL, NULL); + if (err != CRYPT_OK) { + goto error; + } + + err = der_encode_subject_public_key_info(out, outlen, + PKA_RSA, tmp, tmplen, + LTC_ASN1_NULL, NULL, + 0); - err = der_encode_subject_public_key_info(out, outlen, - PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); - error: - XFREE(tmp); - return err; - } + XFREE(tmp); + return err; + } } #endif /* LTC_MRSA */ diff --git a/libtomcrypt/pk/rsa/rsa_exptmod.c b/libtomcrypt/pk/rsa/rsa_exptmod.c index 35ebfe3..b137f9c 100644 --- a/libtomcrypt/pk/rsa/rsa_exptmod.c +++ b/libtomcrypt/pk/rsa/rsa_exptmod.c @@ -15,7 +15,7 @@ /** @file rsa_exptmod.c RSA LTC_PKCS exptmod, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -28,116 +28,145 @@ @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC @param key The RSA key to use @return CRYPT_OK if successful -*/ -int rsa_exptmod(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, int which, - rsa_key *key) +*/ +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key * key) { - mp_int tmp, tmpa, tmpb, rnd, rndi /* inverse of rnd */; - unsigned long x; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* is the key of the right type for the operation? */ - if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { - return CRYPT_PK_NOT_PRIVATE; - } - - /* must be a private or public operation */ - if (which != PK_PRIVATE && which != PK_PUBLIC) { - return CRYPT_PK_INVALID_TYPE; - } - - /* init and copy into tmp */ - if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, &rnd, &rndi, NULL)) != CRYPT_OK) - { return err; } - if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) - { goto error; } - - /* sanity check on the input */ - if (mp_cmp(&key->N, &tmp) == LTC_MP_LT) { - err = CRYPT_PK_INVALID_SIZE; - goto error; - } - - /* are we using the private exponent and is the key optimized? */ - if (which == PK_PRIVATE) { - /* do blinding */ - err = mp_rand(&rnd, mp_count_bits(&key->N)); - if (err != CRYPT_OK) { - goto error; - } - - /* rndi = 1/rnd mod N */ - err = mp_invmod( &rnd, &key->N, &rndi); - if (err != CRYPT_OK) { - goto error; - } - - /* rnd = rnd^e */ - err = mp_exptmod( &rnd, &key->e, &key->N, &rnd); - if (err != CRYPT_OK) { - goto error; - } - - /* tmp = tmp*rnd mod N */ - err = mp_mulmod( &tmp, &rnd, &key->N, &tmp); - if (err != CRYPT_OK) { - goto error; - } - - /* tmpa = tmp^dP mod p */ - if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != CRYPT_OK) { goto error; } - - /* tmpb = tmp^dQ mod q */ - if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != CRYPT_OK) { goto error; } - - /* tmp = (tmpa - tmpb) * qInv (mod p) */ - if ((err = mp_sub(&tmpa, &tmpb, &tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_mulmod(&tmp, &key->qP, &key->p, &tmp)) != CRYPT_OK) { goto error; } - - /* tmp = tmpb + q * tmp */ - if ((err = mp_mul(&tmp, &key->q, &tmp)) != CRYPT_OK) { goto error; } - if ((err = mp_add(&tmp, &tmpb, &tmp)) != CRYPT_OK) { goto error; } - - /* unblind */ - err = mp_mulmod( &tmp, &rndi, &key->N, &tmp); - if (err != CRYPT_OK) { - goto error; - } - } else { - /* exptmod it */ - if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != CRYPT_OK) { goto error; } - } - - /* read it back */ - x = (unsigned long)mp_unsigned_bin_size(&key->N); - if (x > *outlen) { - *outlen = x; - err = CRYPT_BUFFER_OVERFLOW; - goto error; - } - - /* this should never happen ... */ - if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) { - err = CRYPT_ERROR; - goto error; - } - *outlen = x; - - /* convert it */ - zeromem(out, x); - if ((err = mp_to_unsigned_bin(&tmp, out+(x-mp_unsigned_bin_size(&tmp)))) != CRYPT_OK) { goto error; } - - /* clean up and return */ - err = CRYPT_OK; + mp_int tmp, tmpa, tmpb, rnd, rndi /* inverse of rnd */ ; + unsigned long x; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* is the key of the right type for the operation? */ + if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if ((err = + mp_init_multi(&tmp, &tmpa, &tmpb, &rnd, &rndi, + NULL)) != CRYPT_OK) { + return err; + } + if ((err = + mp_read_unsigned_bin(&tmp, (unsigned char *)in, + (int)inlen)) != CRYPT_OK) { + goto error; + } + + /* sanity check on the input */ + if (mp_cmp(&key->N, &tmp) == LTC_MP_LT) { + err = CRYPT_PK_INVALID_SIZE; + goto error; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE) { + /* do blinding */ + err = mp_rand(&rnd, mp_count_bits(&key->N)); + if (err != CRYPT_OK) { + goto error; + } + + /* rndi = 1/rnd mod N */ + err = mp_invmod(&rnd, &key->N, &rndi); + if (err != CRYPT_OK) { + goto error; + } + + /* rnd = rnd^e */ + err = mp_exptmod(&rnd, &key->e, &key->N, &rnd); + if (err != CRYPT_OK) { + goto error; + } + + /* tmp = tmp*rnd mod N */ + err = mp_mulmod(&tmp, &rnd, &key->N, &tmp); + if (err != CRYPT_OK) { + goto error; + } + + /* tmpa = tmp^dP mod p */ + if ((err = + mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != CRYPT_OK) { + goto error; + } + + /* tmpb = tmp^dQ mod q */ + if ((err = + mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != CRYPT_OK) { + goto error; + } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + if ((err = mp_sub(&tmpa, &tmpb, &tmp)) != CRYPT_OK) { + goto error; + } + if ((err = + mp_mulmod(&tmp, &key->qP, &key->p, &tmp)) != CRYPT_OK) { + goto error; + } + + /* tmp = tmpb + q * tmp */ + if ((err = mp_mul(&tmp, &key->q, &tmp)) != CRYPT_OK) { + goto error; + } + if ((err = mp_add(&tmp, &tmpb, &tmp)) != CRYPT_OK) { + goto error; + } + + /* unblind */ + err = mp_mulmod(&tmp, &rndi, &key->N, &tmp); + if (err != CRYPT_OK) { + goto error; + } + } else { + /* exptmod it */ + if ((err = + mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != CRYPT_OK) { + goto error; + } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(&key->N); + if (x > *outlen) { + *outlen = x; + err = CRYPT_BUFFER_OVERFLOW; + goto error; + } + + /* this should never happen ... */ + if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) { + err = CRYPT_ERROR; + goto error; + } + *outlen = x; + + /* convert it */ + zeromem(out, x); + if ((err = + mp_to_unsigned_bin(&tmp, + out + (x - mp_unsigned_bin_size(&tmp)))) != + CRYPT_OK) { + goto error; + } + + /* clean up and return */ + err = CRYPT_OK; error: - mp_clear_multi(&tmp, &tmpa, &tmpb, &rnd, &rndi, NULL); - return err; + mp_clear_multi(&tmp, &tmpa, &tmpb, &rnd, &rndi, NULL); + return err; } #endif diff --git a/libtomcrypt/pk/rsa/rsa_free.c b/libtomcrypt/pk/rsa/rsa_free.c index d38b266..c4c347f 100644 --- a/libtomcrypt/pk/rsa/rsa_free.c +++ b/libtomcrypt/pk/rsa/rsa_free.c @@ -13,7 +13,7 @@ /** @file rsa_free.c Free an RSA key, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -21,10 +21,11 @@ Free an RSA key from memory @param key The RSA key to free */ -void rsa_free(rsa_key *key) +void rsa_free(rsa_key * key) { - LTC_ARGCHKVD(key != NULL); - mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); + LTC_ARGCHKVD(key != NULL); + mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, + &key->p, &key->q, NULL); } #endif diff --git a/libtomcrypt/pk/rsa/rsa_import.c b/libtomcrypt/pk/rsa/rsa_import.c index 87cb103..de8a103 100644 --- a/libtomcrypt/pk/rsa/rsa_import.c +++ b/libtomcrypt/pk/rsa/rsa_import.c @@ -10,11 +10,10 @@ */ #include "tomcrypt.h" - /** @file rsa_import.c Import a LTC_PKCS RSA key, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -25,104 +24,113 @@ @param key [out] Destination for newly imported key @return CRYPT_OK if successful, upon error allocated memory is freed */ -int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key * key) { - int err; - mp_int zero; - unsigned char *tmpbuf=NULL; - unsigned long tmpbuf_len; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(key != NULL); - - /* init key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, - &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - return err; - } - - /* see if the OpenSSL DER format RSA public key will work */ - tmpbuf_len = MAX_RSA_SIZE * 8; - tmpbuf = XCALLOC(1, tmpbuf_len); - if (tmpbuf == NULL) { - err = CRYPT_MEM; - goto LBL_ERR; - } - - err = der_decode_subject_public_key_info(in, inlen, - PKA_RSA, tmpbuf, &tmpbuf_len, - LTC_ASN1_NULL, NULL, 0); - - if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ - - /* now it should be SEQUENCE { INTEGER, INTEGER } */ - if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - - XFREE(tmpbuf); - - key->type = PK_PUBLIC; - return CRYPT_OK; - } - - XFREE(tmpbuf); - - /* not SSL public key, try to match against LTC_PKCS #1 standards */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - - if (mp_cmp_d(&key->N, 0) == LTC_MP_EQ) { - if ((err = mp_init(&zero)) != CRYPT_OK) { - goto LBL_ERR; - } - /* it's a private key */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, &zero, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_INTEGER, 1UL, &key->d, - LTC_ASN1_INTEGER, 1UL, &key->p, - LTC_ASN1_INTEGER, 1UL, &key->q, - LTC_ASN1_INTEGER, 1UL, &key->dP, - LTC_ASN1_INTEGER, 1UL, &key->dQ, - LTC_ASN1_INTEGER, 1UL, &key->qP, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - mp_clear(&zero); - goto LBL_ERR; - } - mp_clear(&zero); - key->type = PK_PRIVATE; - } else if (mp_cmp_d(&key->N, 1) == LTC_MP_EQ) { - /* we don't support multi-prime RSA */ - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; - } else { - /* it's a public key and we lack e */ - if ((err = der_decode_sequence_multi(in, inlen, - LTC_ASN1_INTEGER, 1UL, &key->N, - LTC_ASN1_INTEGER, 1UL, &key->e, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { - goto LBL_ERR; - } - key->type = PK_PUBLIC; - } - return CRYPT_OK; + int err; + mp_int zero; + unsigned char *tmpbuf = NULL; + unsigned long tmpbuf_len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(key != NULL); + + /* init key */ + if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, + NULL)) != CRYPT_OK) { + return err; + } + + /* see if the OpenSSL DER format RSA public key will work */ + tmpbuf_len = MAX_RSA_SIZE * 8; + tmpbuf = XCALLOC(1, tmpbuf_len); + if (tmpbuf == NULL) { + err = CRYPT_MEM; + goto LBL_ERR; + } + + err = der_decode_subject_public_key_info(in, inlen, + PKA_RSA, tmpbuf, &tmpbuf_len, + LTC_ASN1_NULL, NULL, 0); + + if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */ + + /* now it should be SEQUENCE { INTEGER, INTEGER } */ + if ((err = der_decode_sequence_multi(tmpbuf, tmpbuf_len, + LTC_ASN1_INTEGER, 1UL, + &key->N, LTC_ASN1_INTEGER, + 1UL, &key->e, LTC_ASN1_EOL, + 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + XFREE(tmpbuf); + + key->type = PK_PUBLIC; + return CRYPT_OK; + } + + XFREE(tmpbuf); + + /* not SSL public key, try to match against LTC_PKCS #1 standards */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_EOL, 0UL, + NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + + if (mp_cmp_d(&key->N, 0) == LTC_MP_EQ) { + if ((err = mp_init(&zero)) != CRYPT_OK) { + goto LBL_ERR; + } + /* it's a private key */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, + &zero, LTC_ASN1_INTEGER, + 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, + &key->e, LTC_ASN1_INTEGER, + 1UL, &key->d, + LTC_ASN1_INTEGER, 1UL, + &key->p, LTC_ASN1_INTEGER, + 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, + &key->dP, LTC_ASN1_INTEGER, + 1UL, &key->dQ, + LTC_ASN1_INTEGER, 1UL, + &key->qP, LTC_ASN1_EOL, + 0UL, NULL)) != CRYPT_OK) { + mp_clear(&zero); + goto LBL_ERR; + } + mp_clear(&zero); + key->type = PK_PRIVATE; + } else if (mp_cmp_d(&key->N, 1) == LTC_MP_EQ) { + /* we don't support multi-prime RSA */ + err = CRYPT_PK_INVALID_TYPE; + goto LBL_ERR; + } else { + /* it's a public key and we lack e */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, + &key->N, LTC_ASN1_INTEGER, + 1UL, &key->e, LTC_ASN1_EOL, + 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; + } + key->type = PK_PUBLIC; + } + return CRYPT_OK; LBL_ERR: - XFREE(tmpbuf); - mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); - return err; + XFREE(tmpbuf); + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, + &key->p, &key->q, NULL); + return err; } #endif /* LTC_MRSA */ - /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ /* $Revision: 1.23 $ */ /* $Date: 2007/05/12 14:32:35 $ */ diff --git a/libtomcrypt/pk/rsa/rsa_make_key.c b/libtomcrypt/pk/rsa/rsa_make_key.c index 6718f09..204f9c5 100644 --- a/libtomcrypt/pk/rsa/rsa_make_key.c +++ b/libtomcrypt/pk/rsa/rsa_make_key.c @@ -13,7 +13,7 @@ /** @file rsa_make_key.c RSA key generation, Tom St Denis -*/ +*/ #ifdef LTC_MRSA @@ -24,78 +24,124 @@ @param key [out] Destination of a newly created private key pair @return CRYPT_OK if successful, upon error all allocated ram is freed */ -int rsa_make_key(int size, long e, rsa_key *key) +int rsa_make_key(int size, long e, rsa_key * key) { - mp_int p, q, tmp1, tmp2, tmp3; - int err; - - LTC_ARGCHK(key != NULL); - - if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { - return CRYPT_INVALID_KEYSIZE; - } - - if ((e < 3) || ((e & 1) == 0)) { - return CRYPT_INVALID_ARG; - } - - if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { - return err; - } - - /* make primes p and q (optimization provided by Wayne Scott) */ - if ((err = mp_set_int(&tmp3, e)) != CRYPT_OK) { goto cleanup; } /* tmp3 = e */ - - /* make prime "p" */ - do { - if ((err = rand_prime( &p, size/2)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_sub_d( &p, 1, &tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = p-1 */ - if ((err = mp_gcd( &tmp1, &tmp3, &tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = gcd(p-1, e) */ - } while (mp_cmp_d( &tmp2, 1) != 0); /* while e divides p-1 */ - - /* make prime "q" */ - do { - if ((err = rand_prime( &q, size/2)) != CRYPT_OK) { goto cleanup; } - if ((err = mp_sub_d( &q, 1, &tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = q-1 */ - if ((err = mp_gcd( &tmp1, &tmp3, &tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = gcd(q-1, e) */ - } while (mp_cmp_d( &tmp2, 1) != 0); /* while e divides q-1 */ - - /* tmp1 = lcm(p-1, q-1) */ - if ((err = mp_sub_d( &p, 1, &tmp2)) != CRYPT_OK) { goto cleanup; } /* tmp2 = p-1 */ - /* tmp1 = q-1 (previous do/while loop) */ - if ((err = mp_lcm( &tmp1, &tmp2, &tmp1)) != CRYPT_OK) { goto cleanup; } /* tmp1 = lcm(p-1, q-1) */ - - /* make key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { - goto cleanup; - } - - if ((err = mp_set_int( &key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ - if ((err = mp_invmod( &key->e, &tmp1, &key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ - if ((err = mp_mul( &p, &q, &key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ - - /* optimize for CRT now */ - /* find d mod q-1 and d mod p-1 */ - if ((err = mp_sub_d( &p, 1, &tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ - if ((err = mp_sub_d( &q, 1, &tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ - if ((err = mp_mod( &key->d, &tmp1, &key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ - if ((err = mp_mod( &key->d, &tmp2, &key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ - if ((err = mp_invmod( &q, &p, &key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ - - if ((err = mp_copy( &p, &key->p)) != CRYPT_OK) { goto errkey; } - if ((err = mp_copy( &q, &key->q)) != CRYPT_OK) { goto errkey; } - - /* set key type (in this case it's CRT optimized) */ - key->type = PK_PRIVATE; - - /* return ok and free temps */ - err = CRYPT_OK; - goto cleanup; + mp_int p, q, tmp1, tmp2, tmp3; + int err; + + LTC_ARGCHK(key != NULL); + + if ((size < (MIN_RSA_SIZE / 8)) || (size > (MAX_RSA_SIZE / 8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = + mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { + return err; + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if ((err = mp_set_int(&tmp3, e)) != CRYPT_OK) { + goto cleanup; + } + + /* tmp3 = e */ + /* make prime "p" */ + do { + if ((err = rand_prime(&p, size / 2)) != CRYPT_OK) { + goto cleanup; + } + if ((err = mp_sub_d(&p, 1, &tmp1)) != CRYPT_OK) { + goto cleanup; + } /* tmp1 = p-1 */ + if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != CRYPT_OK) { + goto cleanup; + } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if ((err = rand_prime(&q, size / 2)) != CRYPT_OK) { + goto cleanup; + } + if ((err = mp_sub_d(&q, 1, &tmp1)) != CRYPT_OK) { + goto cleanup; + } /* tmp1 = q-1 */ + if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != CRYPT_OK) { + goto cleanup; + } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if ((err = mp_sub_d(&p, 1, &tmp2)) != CRYPT_OK) { + goto cleanup; + } + /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if ((err = mp_lcm(&tmp1, &tmp2, &tmp1)) != CRYPT_OK) { + goto cleanup; + } + + /* tmp1 = lcm(p-1, q-1) */ + /* make key */ + if ((err = + mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { + goto cleanup; + } + + if ((err = mp_set_int(&key->e, e)) != CRYPT_OK) { + goto errkey; + } /* key->e = e */ + if ((err = mp_invmod(&key->e, &tmp1, &key->d)) != CRYPT_OK) { + goto errkey; + } /* key->d = 1/e mod lcm(p-1,q-1) */ + if ((err = mp_mul(&p, &q, &key->N)) != CRYPT_OK) { + goto errkey; + } + + /* key->N = pq */ + /* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if ((err = mp_sub_d(&p, 1, &tmp1)) != CRYPT_OK) { + goto errkey; + } /* tmp1 = q-1 */ + if ((err = mp_sub_d(&q, 1, &tmp2)) != CRYPT_OK) { + goto errkey; + } /* tmp2 = p-1 */ + if ((err = mp_mod(&key->d, &tmp1, &key->dP)) != CRYPT_OK) { + goto errkey; + } /* dP = d mod p-1 */ + if ((err = mp_mod(&key->d, &tmp2, &key->dQ)) != CRYPT_OK) { + goto errkey; + } /* dQ = d mod q-1 */ + if ((err = mp_invmod(&q, &p, &key->qP)) != CRYPT_OK) { + goto errkey; + } + /* qP = 1/q mod p */ + if ((err = mp_copy(&p, &key->p)) != CRYPT_OK) { + goto errkey; + } + if ((err = mp_copy(&q, &key->q)) != CRYPT_OK) { + goto errkey; + } + + /* set key type (in this case it's CRT optimized) */ + key->type = PK_PRIVATE; + + /* return ok and free temps */ + err = CRYPT_OK; + goto cleanup; errkey: - mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, + &key->p, &key->q, NULL); cleanup: - mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL); - return err; + mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL); + return err; } #endif diff --git a/libtomcrypt/pk/rsa/rsa_sign_hash.c b/libtomcrypt/pk/rsa/rsa_sign_hash.c index faf13d2..a0c993d 100644 --- a/libtomcrypt/pk/rsa/rsa_sign_hash.c +++ b/libtomcrypt/pk/rsa/rsa_sign_hash.c @@ -11,7 +11,6 @@ #include "tomcrypt.h" #include "ncr-int.h" - /** @file rsa_sign_hash.c RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange @@ -31,96 +30,99 @@ @param key The private RSA key to use @return CRYPT_OK if successful */ -int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - int padding, - const struct algo_properties_st *hash, unsigned long saltlen, - rsa_key *key) +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + const struct algo_properties_st *hash, + unsigned long saltlen, rsa_key * key) { - unsigned long modulus_bitlen, modulus_bytelen, x, y; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* valid padding? */ - if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - if ((err = hash_is_valid(hash)) != CRYPT_OK) { - return err; - } - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits((&key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size((&key->N)); - if (modulus_bytelen > *outlen) { - *outlen = modulus_bytelen; - return CRYPT_BUFFER_OVERFLOW; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - /* PSS pad the key */ - x = *outlen; - if ((err = pkcs_1_pss_encode(in, inlen, saltlen, - hash, modulus_bitlen, out, &x)) != CRYPT_OK) { - return err; - } - } else { - /* LTC_PKCS #1 v1.5 pad the hash */ - unsigned char *tmpin; - ltc_asn1_list digestinfo[2], siginfo[2]; - oid_st st; - - /* not all hashes have OIDs... so sad */ - if (hash_get_oid(hash, &st) != CRYPT_OK) { - return CRYPT_INVALID_ARG; - } - - /* construct the SEQUENCE - SEQUENCE { - SEQUENCE {hashoid OID - blah NULL - } - hash OCTET STRING - } - */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, st.OID, st.OIDlen); - LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); - LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); - LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); - - /* allocate memory for the encoding */ - y = mp_unsigned_bin_size(&key->N); - tmpin = XMALLOC(y); - if (tmpin == NULL) { - return CRYPT_MEM; - } - - if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { - XFREE(tmpin); - return err; - } - - x = *outlen; - if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_LTC_PKCS_1_EMSA, - modulus_bitlen, - out, &x)) != CRYPT_OK) { - XFREE(tmpin); - return err; - } - XFREE(tmpin); - } - - /* RSA encode it */ - return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key); + unsigned long modulus_bitlen, modulus_bytelen, x, y; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + /* valid padding? */ + if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((&key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((&key->N)); + if (modulus_bytelen > *outlen) { + *outlen = modulus_bytelen; + return CRYPT_BUFFER_OVERFLOW; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS pad the key */ + x = *outlen; + if ((err = pkcs_1_pss_encode(in, inlen, saltlen, + hash, modulus_bitlen, out, + &x)) != CRYPT_OK) { + return err; + } + } else { + /* LTC_PKCS #1 v1.5 pad the hash */ + unsigned char *tmpin; + ltc_asn1_list digestinfo[2], siginfo[2]; + oid_st st; + + /* not all hashes have OIDs... so sad */ + if (hash_get_oid(hash, &st) != CRYPT_OK) { + return CRYPT_INVALID_ARG; + } + + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, st.OID, + st.OIDlen); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); + + /* allocate memory for the encoding */ + y = mp_unsigned_bin_size(&key->N); + tmpin = XMALLOC(y); + if (tmpin == NULL) { + return CRYPT_MEM; + } + + if ((err = + der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + + x = *outlen; + if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_LTC_PKCS_1_EMSA, + modulus_bitlen, + out, &x)) != CRYPT_OK) { + XFREE(tmpin); + return err; + } + XFREE(tmpin); + } + + /* RSA encode it */ + return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key); } #endif /* LTC_MRSA */ diff --git a/libtomcrypt/pk/rsa/rsa_verify_hash.c b/libtomcrypt/pk/rsa/rsa_verify_hash.c index 803b7cd..cb250cc 100644 --- a/libtomcrypt/pk/rsa/rsa_verify_hash.c +++ b/libtomcrypt/pk/rsa/rsa_verify_hash.c @@ -11,7 +11,6 @@ #include "tomcrypt.h" #include "ncr-int.h" - /** @file rsa_verify_hash.c RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange @@ -32,135 +31,146 @@ @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ -int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int padding, - const struct algo_properties_st *hash_algo, unsigned long saltlen, - int *stat, rsa_key *key) +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + const struct algo_properties_st *hash_algo, + unsigned long saltlen, int *stat, rsa_key * key) { - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - unsigned char *tmpbuf; - - LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); - LTC_ARGCHK(key != NULL); - - /* default to invalid */ - *stat = 0; - - /* valid padding? */ - - if ((padding != LTC_LTC_PKCS_1_V1_5) && - (padding != LTC_LTC_PKCS_1_PSS)) { - return CRYPT_PK_INVALID_PADDING; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - /* valid hash ? */ - if ((err = hash_is_valid(hash_algo)) != CRYPT_OK) { - return err; - } - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits( (&key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size( (&key->N)); - if (modulus_bytelen != siglen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate temp buffer for decoded sig */ - tmpbuf = XMALLOC(siglen); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - /* RSA decode it */ - x = siglen; - if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { - XFREE(tmpbuf); - return err; - } - - /* make sure the output is the right size */ - if (x != siglen) { - XFREE(tmpbuf); - return CRYPT_INVALID_PACKET; - } - - if (padding == LTC_LTC_PKCS_1_PSS) { - /* PSS decode and verify it */ - err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_algo, modulus_bitlen, stat); - } else { - /* LTC_PKCS #1 v1.5 decode it */ - unsigned char *out; - unsigned long outlen, loid[16]; - int decoded; - ltc_asn1_list digestinfo[2], siginfo[2]; - oid_st st; - - /* not all hashes have OIDs... so sad */ - if (hash_get_oid(hash_algo, &st) != CRYPT_OK) { - err = CRYPT_INVALID_ARG; - goto bail_2; - } - - /* allocate temp buffer for decoded hash */ - outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; - out = XMALLOC(outlen); - if (out == NULL) { - err = CRYPT_MEM; - goto bail_2; - } - - if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } - - /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ - /* construct the SEQUENCE - SEQUENCE { - SEQUENCE {hashoid OID - blah NULL - } - hash OCTET STRING - } - */ - LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); - LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); - LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); - LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); - - if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { - XFREE(out); - goto bail_2; - } - - /* test OID */ - if ((digestinfo[0].size == st.OIDlen) && - (XMEMCMP(digestinfo[0].data, st.OID, sizeof(unsigned long) * st.OIDlen) == 0) && - (siginfo[1].size == hashlen) && - (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { - *stat = 1; - } - + unsigned long modulus_bitlen, modulus_bytelen, x; + int err; + unsigned char *tmpbuf; + + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* valid padding? */ + + if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { + return CRYPT_PK_INVALID_PADDING; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* valid hash ? */ + if ((err = hash_is_valid(hash_algo)) != CRYPT_OK) { + return err; + } + } + + /* get modulus len in bits */ + modulus_bitlen = mp_count_bits((&key->N)); + + /* outlen must be at least the size of the modulus */ + modulus_bytelen = mp_unsigned_bin_size((&key->N)); + if (modulus_bytelen != siglen) { + return CRYPT_INVALID_PACKET; + } + + /* allocate temp buffer for decoded sig */ + tmpbuf = XMALLOC(siglen); + if (tmpbuf == NULL) { + return CRYPT_MEM; + } + + /* RSA decode it */ + x = siglen; + if ((err = + rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, + key)) != CRYPT_OK) { + XFREE(tmpbuf); + return err; + } + + /* make sure the output is the right size */ + if (x != siglen) { + XFREE(tmpbuf); + return CRYPT_INVALID_PACKET; + } + + if (padding == LTC_LTC_PKCS_1_PSS) { + /* PSS decode and verify it */ + err = + pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, + hash_algo, modulus_bitlen, stat); + } else { + /* LTC_PKCS #1 v1.5 decode it */ + unsigned char *out; + unsigned long outlen, loid[16]; + int decoded; + ltc_asn1_list digestinfo[2], siginfo[2]; + oid_st st; + + /* not all hashes have OIDs... so sad */ + if (hash_get_oid(hash_algo, &st) != CRYPT_OK) { + err = CRYPT_INVALID_ARG; + goto bail_2; + } + + /* allocate temp buffer for decoded hash */ + outlen = + ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; + out = XMALLOC(outlen); + if (out == NULL) { + err = CRYPT_MEM; + goto bail_2; + } + + if ((err = + pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, + modulus_bitlen, out, &outlen, + &decoded)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ + /* construct the SEQUENCE + SEQUENCE { + SEQUENCE {hashoid OID + blah NULL + } + hash OCTET STRING + } + */ + LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, + sizeof(loid) / sizeof(loid[0])); + LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); + LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); + LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); + + if ((err = + der_decode_sequence(out, outlen, siginfo, + 2)) != CRYPT_OK) { + XFREE(out); + goto bail_2; + } + + /* test OID */ + if ((digestinfo[0].size == st.OIDlen) && + (XMEMCMP + (digestinfo[0].data, st.OID, + sizeof(unsigned long) * st.OIDlen) == 0) + && (siginfo[1].size == hashlen) + && (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { + *stat = 1; + } #ifdef LTC_CLEAN_STACK - zeromem(out, outlen); + zeromem(out, outlen); #endif - XFREE(out); - } + XFREE(out); + } bail_2: #ifdef LTC_CLEAN_STACK - zeromem(tmpbuf, siglen); + zeromem(tmpbuf, siglen); #endif - XFREE(tmpbuf); - return err; + XFREE(tmpbuf); + return err; } #endif /* LTC_MRSA */ |
