Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/pk/rsa/rsa_sign_hash.c
4396 views
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
#include "tomcrypt.h"
10
11
/**
12
@file rsa_sign_hash.c
13
RSA PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange
14
*/
15
16
#ifdef LTC_MRSA
17
18
/**
19
PKCS #1 pad then sign
20
@param in The hash to sign
21
@param inlen The length of the hash to sign (octets)
22
@param out [out] The signature
23
@param outlen [in/out] The max size and resulting size of the signature
24
@param padding Type of padding (LTC_PKCS_1_PSS, LTC_PKCS_1_V1_5 or LTC_PKCS_1_V1_5_NA1)
25
@param prng An active PRNG state
26
@param prng_idx The index of the PRNG desired
27
@param hash_idx The index of the hash desired
28
@param saltlen The length of the salt desired (octets)
29
@param key The private RSA key to use
30
@return CRYPT_OK if successful
31
*/
32
int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen,
33
unsigned char *out, unsigned long *outlen,
34
int padding,
35
prng_state *prng, int prng_idx,
36
int hash_idx, unsigned long saltlen,
37
rsa_key *key)
38
{
39
unsigned long modulus_bitlen, modulus_bytelen, x, y;
40
int err;
41
42
LTC_ARGCHK(in != NULL);
43
LTC_ARGCHK(out != NULL);
44
LTC_ARGCHK(outlen != NULL);
45
LTC_ARGCHK(key != NULL);
46
47
/* valid padding? */
48
if ((padding != LTC_PKCS_1_V1_5) &&
49
(padding != LTC_PKCS_1_PSS) &&
50
(padding != LTC_PKCS_1_V1_5_NA1)) {
51
return CRYPT_PK_INVALID_PADDING;
52
}
53
54
if (padding == LTC_PKCS_1_PSS) {
55
/* valid prng ? */
56
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
57
return err;
58
}
59
}
60
61
if (padding != LTC_PKCS_1_V1_5_NA1) {
62
/* valid hash ? */
63
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
64
return err;
65
}
66
}
67
68
/* get modulus len in bits */
69
modulus_bitlen = mp_count_bits((key->N));
70
71
/* outlen must be at least the size of the modulus */
72
modulus_bytelen = mp_unsigned_bin_size((key->N));
73
if (modulus_bytelen > *outlen) {
74
*outlen = modulus_bytelen;
75
return CRYPT_BUFFER_OVERFLOW;
76
}
77
78
if (padding == LTC_PKCS_1_PSS) {
79
/* PSS pad the key */
80
x = *outlen;
81
if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx,
82
hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) {
83
return err;
84
}
85
} else {
86
/* PKCS #1 v1.5 pad the hash */
87
unsigned char *tmpin;
88
89
if (padding == LTC_PKCS_1_V1_5) {
90
ltc_asn1_list digestinfo[2], siginfo[2];
91
/* not all hashes have OIDs... so sad */
92
if (hash_descriptor[hash_idx].OIDlen == 0) {
93
return CRYPT_INVALID_ARG;
94
}
95
96
/* construct the SEQUENCE
97
SEQUENCE {
98
SEQUENCE {hashoid OID
99
blah NULL
100
}
101
hash OCTET STRING
102
}
103
*/
104
LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen);
105
LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0);
106
LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
107
LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen);
108
109
/* allocate memory for the encoding */
110
y = mp_unsigned_bin_size(key->N);
111
tmpin = XMALLOC(y);
112
if (tmpin == NULL) {
113
return CRYPT_MEM;
114
}
115
116
if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) {
117
XFREE(tmpin);
118
return err;
119
}
120
} else {
121
/* set the pointer and data-length to the input values */
122
tmpin = (unsigned char *)in;
123
y = inlen;
124
}
125
126
x = *outlen;
127
err = pkcs_1_v1_5_encode(tmpin, y, LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, out, &x);
128
129
if (padding == LTC_PKCS_1_V1_5) {
130
XFREE(tmpin);
131
}
132
133
if (err != CRYPT_OK) {
134
return err;
135
}
136
}
137
138
/* RSA encode it */
139
return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
140
}
141
142
#endif /* LTC_MRSA */
143
144