Mercurial > dropbear
comparison libtomcrypt/src/pk/rsa/rsa_sign_hash.c @ 399:a707e6148060
merge of '5fdf69ca60d1683cdd9f4c2595134bed26394834'
and '6b61c50f4cf888bea302ac8fcf5dbb573b443251'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:34 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
394:17d097fc111c | 399:a707e6148060 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | |
10 */ | |
11 #include "tomcrypt.h" | |
12 | |
13 /** | |
14 @file rsa_sign_hash.c | |
15 RSA PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange | |
16 */ | |
17 | |
18 #ifdef MRSA | |
19 | |
20 /** | |
21 PKCS #1 pad then sign | |
22 @param in The hash to sign | |
23 @param inlen The length of the hash to sign (octets) | |
24 @param out [out] The signature | |
25 @param outlen [in/out] The max size and resulting size of the signature | |
26 @param padding Type of padding (LTC_PKCS_1_PSS or LTC_PKCS_1_V1_5) | |
27 @param prng An active PRNG state | |
28 @param prng_idx The index of the PRNG desired | |
29 @param hash_idx The index of the hash desired | |
30 @param saltlen The length of the salt desired (octets) | |
31 @param key The private RSA key to use | |
32 @return CRYPT_OK if successful | |
33 */ | |
34 int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, | |
35 unsigned char *out, unsigned long *outlen, | |
36 int padding, | |
37 prng_state *prng, int prng_idx, | |
38 int hash_idx, unsigned long saltlen, | |
39 rsa_key *key) | |
40 { | |
41 unsigned long modulus_bitlen, modulus_bytelen, x, y; | |
42 int err; | |
43 | |
44 LTC_ARGCHK(in != NULL); | |
45 LTC_ARGCHK(out != NULL); | |
46 LTC_ARGCHK(outlen != NULL); | |
47 LTC_ARGCHK(key != NULL); | |
48 | |
49 /* valid padding? */ | |
50 if ((padding != LTC_PKCS_1_V1_5) && (padding != LTC_PKCS_1_PSS)) { | |
51 return CRYPT_PK_INVALID_PADDING; | |
52 } | |
53 | |
54 if (padding == LTC_PKCS_1_PSS) { | |
55 /* valid prng and hash ? */ | |
56 if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { | |
57 return err; | |
58 } | |
59 if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { | |
60 return err; | |
61 } | |
62 } | |
63 | |
64 /* get modulus len in bits */ | |
65 modulus_bitlen = mp_count_bits((key->N)); | |
66 | |
67 /* outlen must be at least the size of the modulus */ | |
68 modulus_bytelen = mp_unsigned_bin_size((key->N)); | |
69 if (modulus_bytelen > *outlen) { | |
70 *outlen = modulus_bytelen; | |
71 return CRYPT_BUFFER_OVERFLOW; | |
72 } | |
73 | |
74 if (padding == LTC_PKCS_1_PSS) { | |
75 /* PSS pad the key */ | |
76 x = *outlen; | |
77 if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, | |
78 hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { | |
79 return err; | |
80 } | |
81 } else { | |
82 /* PKCS #1 v1.5 pad the hash */ | |
83 unsigned char *tmpin; | |
84 ltc_asn1_list digestinfo[2], siginfo[2]; | |
85 | |
86 /* not all hashes have OIDs... so sad */ | |
87 if (hash_descriptor[hash_idx].OIDlen == 0) { | |
88 return CRYPT_INVALID_ARG; | |
89 } | |
90 | |
91 /* construct the SEQUENCE | |
92 SEQUENCE { | |
93 SEQUENCE {hashoid OID | |
94 blah NULL | |
95 } | |
96 hash OCTET STRING | |
97 } | |
98 */ | |
99 LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); | |
100 LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); | |
101 LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); | |
102 LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); | |
103 | |
104 /* allocate memory for the encoding */ | |
105 y = mp_unsigned_bin_size(key->N); | |
106 tmpin = XMALLOC(y); | |
107 if (tmpin == NULL) { | |
108 return CRYPT_MEM; | |
109 } | |
110 | |
111 if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { | |
112 XFREE(tmpin); | |
113 return err; | |
114 } | |
115 | |
116 x = *outlen; | |
117 if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA, | |
118 modulus_bitlen, NULL, 0, | |
119 out, &x)) != CRYPT_OK) { | |
120 XFREE(tmpin); | |
121 return err; | |
122 } | |
123 XFREE(tmpin); | |
124 } | |
125 | |
126 /* RSA encode it */ | |
127 return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); | |
128 } | |
129 | |
130 #endif /* MRSA */ | |
131 | |
132 /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_sign_hash.c,v $ */ | |
133 /* $Revision: 1.9 $ */ | |
134 /* $Date: 2006/11/09 23:15:39 $ */ |