diff options
Diffstat (limited to 'libtomcrypt/pk/rsa/rsa_sign_hash.c')
-rw-r--r-- | libtomcrypt/pk/rsa/rsa_sign_hash.c | 182 |
1 files changed, 92 insertions, 90 deletions
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 */ |