-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrsassa_pss.h
More file actions
224 lines (214 loc) · 8.6 KB
/
Copy pathrsassa_pss.h
File metadata and controls
224 lines (214 loc) · 8.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/*
* Copyright (c) 2025 Emil Lenngren
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#ifndef P_Q_MAX
#define P_Q_MAX(p, q) ((p) > (q) ? (p) : (q))
#endif
#define RSASSA_PSS_VERIFY_TEMP_AREA_NUM_UINT32(public_key_n_length_bytes) \
(7 * ((((public_key_n_length_bytes) + 31) & ~31) / sizeof(uint32_t)))
#define RSASSA_PSS_SIGN_TEMP_AREA_NUM_UINT32(private_key_p_length_bytes, private_key_q_length_bytes) \
(25 * (((P_Q_MAX((private_key_p_length_bytes), (private_key_q_length_bytes)) + 31) & ~31) / sizeof(uint32_t)))
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type definition for a hash function callback.
*
* This function computes a cryptographic hash over a given input buffer.
*
* @param[in] user_data
* Opaque pointer to user-defined data passed through to the callback.
*
* @param[out] output
* Buffer to store the resulting hash.
*
* @param[in] input
* Pointer to the input data to be hashed.
*
* @param[in] input_length_bytes
* Length of the input data in bytes.
*
* @return Zero on success, non-zero on failure.
*/
typedef int (*hash_fn)(void *user_data, uint8_t *output, const uint8_t *input, size_t input_length_bytes);
/**
* @brief Verifies an RSASSA-PSS signature against a given message hash.
*
* This function verifies a PSS-padded RSA signature using a given hash
* function according to RFC 8017 Section 8.1.2.
*
* The MGF used is MGF1 with the same hash function as is used on the message.
*
* The salt length used is the same as the message hash length.
*
* @param[in] public_key_e
* Pointer to the RSA public exponent \c e in big-endian byte order.
*
* @param[in] public_key_e_length_bytes
* Length of \p public_key_e in bytes.
*
* @param[in] public_key_n
* Pointer to the RSA modulus \c n in big-endian byte order.
* The first byte (most significant) must be non-zero, or an error will be returned.
*
* @param[in] public_key_n_length_bytes
* Length of \p public_key_n in bytes.
*
* @param[in] message_hash
* Pointer to the precomputed message hash to be verified.
*
* @param[in] signature
* Pointer to the signature to be verified.
*
* @param[in] signature_length_bytes
* Length of \p signature in bytes.
*
* @param[in] hash_function
* Pointer to a hash function callback of type ::hash_fn.
* This function must implement the same hash function used to produce \p message_hash.
*
* @param[in] hash_function_user_data
* Pointer to user-defined data passed to \p hash_function.
* Can be \c nullptr if unused by the hash function.
*
* @param[in] hash_length_bytes
* Length in bytes of the hash function output (e.g., 32 for SHA-256).
*
* @param[in,out] temp_area
* Pointer to an array of \c uint32_t (temporary workspace).
* Use the ::RSASSA_PSS_VERIFY_TEMP_AREA_NUM_UINT32 macro to calculate the required size.
*
* @retval 0 The signature is valid.
* @retval -1 The signature is invalid or basic verification checks on the public key failed.
* @retval -2 The hash function failed. The user_data parameter could be used for communicating the specific failure.
*/
int rsassa_pss_verify_hash(
const uint8_t *public_key_e, size_t public_key_e_length_bytes,
const uint8_t *public_key_n, size_t public_key_n_length_bytes,
const uint8_t *message_hash,
const uint8_t *signature, size_t signature_length_bytes,
hash_fn hash_function,
void *hash_function_user_data,
size_t hash_length_bytes,
uint32_t *temp_area);
/**
* @brief Creates an RSASSA-PSS signature for a given message hash.
*
* This function generates a PSS-padded RSA signature using CRT optimization
* and a specified hash function according to RFC 8017 Section 8.1.1.
*
* The MGF used is MGF1 with the same hash function as is used on the message.
*
* The salt length used is the same as the message hash length.
*
* The behaviour of this function is undefined if the private key is invalid,
* or if the requirements for the parameters are not satisfied.
*
* @param[out] signature
* Buffer where the resulting signature will be written.
* Must be the same length as \p private_key_n.
*
* @param[in] private_key_n
* Pointer to the RSA modulus \c n in big-endian byte order.
* The first byte (most significant) must be non-zero.
*
* @param[in] private_key_n_length_bytes
* Length of \p private_key_n in bytes.
*
* @param[in] private_key_p
* Pointer to the first prime factor \c p, in big-endian byte order.
*
* @param[in] private_key_p_length_bytes
* Length of \p private_key_p in bytes.
*
* @param[in] private_key_q
* Pointer to the second prime factor \c q, in big-endian byte order.
*
* @param[in] private_key_q_length_bytes
* Length of \p private_key_q in bytes.
*
* @param[in] private_key_q_inv
* Pointer to the modular inverse of \c q mod \c p, in big-endian byte order.
*
* @param[in] private_key_q_inv_length_bytes
* Length of \p private_key_q_inv in bytes.
*
* @param[in] private_key_dp
* Pointer to the CRT exponent \c dP = d mod (p-1), in big-endian byte order.
*
* @param[in] private_key_dp_length_bytes
* Length of \p private_key_dp in bytes.
*
* @param[in] private_key_dq
* Pointer to the CRT exponent \c dQ = d mod (q-1), in big-endian byte order.
*
* @param[in] private_key_dq_length_bytes
* Length of \p private_key_dq in bytes.
*
* @param[in] message_hash
* Pointer to the precomputed hash of the message to be signed.
*
* @param[in] randomly_generated_salt
* Pointer to a cryptographically securely generated random salt of size \p hash_length_bytes.
*
* @param[in] hash_function
* Pointer to a hash function callback of type ::hash_fn.
* This function must implement the same hash function used to produce \p message_hash.
*
* @param[in] hash_function_user_data
* Pointer to user-defined data passed to \p hash_function.
* Can be \c nullptr if unused by the hash function.
*
* @param[in] hash_length_bytes
* Length in bytes of the hash function output (e.g., 32 for SHA-256).
*
* @param[in,out] temp_area
* Pointer to an array of \c uint32_t (temporary workspace).
* Use the ::RSASSA_PSS_SIGN_TEMP_AREA_NUM_UINT32 macro to calculate the required size.
*
* @retval 0 Signature was generated successfully.
* @retval -1 The modulus is too small for the given hash function output length.
* @retval -2 The hash function failed. The user_data parameter could be used for communicating the specific failure.
*/
int rsassa_pss_sign_hash(
uint8_t *signature,
const uint8_t *private_key_n, size_t private_key_n_length_bytes,
const uint8_t *private_key_p, size_t private_key_p_length_bytes,
const uint8_t *private_key_q, size_t private_key_q_length_bytes,
const uint8_t *private_key_q_inv, size_t private_key_q_inv_length_bytes,
const uint8_t *private_key_dp, size_t private_key_dp_length_bytes,
const uint8_t *private_key_dq, size_t private_key_dq_length_bytes,
const uint8_t *message_hash,
const uint8_t *randomly_generated_salt,
hash_fn hash_function,
void *hash_function_user_data,
size_t hash_length_bytes,
uint32_t *temp_area
);
#ifdef __cplusplus
}
#endif