Software APIs
rsa_padding.h
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #ifndef OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_RSA_RSA_PADDING_H_
6 #define OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_RSA_RSA_PADDING_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
12 #include "sw/device/lib/crypto/impl/rsa/rsa_datatypes.h"
13 #include "sw/device/lib/crypto/impl/status.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif // __cplusplus
19 
20 /**
21  * Encode the message with PKCS#1 v1.5 encoding (RFC 8017, section 9.2).
22  *
23  * The caller must ensure that `encoded_message_len` 32-bit words are allocated
24  * in the output buffer.
25  *
26  * We encode the message in reversed byte-order from the RFC because OTBN
27  * interprets the message as a fully little-endian integer.
28  *
29  * @param message_digest Message digest to encode.
30  * @param encoded_message_len Intended encoded message length in 32-bit words.
31  * @param[out] encoded_message Encoded message.
32  * @return Result of the operation (OK or error).
33  */
35 status_t rsa_padding_pkcs1v15_encode(
36  const otcrypto_hash_digest_t message_digest, size_t encoded_message_len,
37  uint32_t *encoded_message);
38 
39 /**
40  * Check if the PKCS#1 v1.5 encoded message represents the message.
41  *
42  * If the encoded message does not match the message, this function will return
43  * an OK status and write `kHardenedBoolFalse` into the result buffer. The
44  * caller should not interpret an OK status as a match between the encoded and
45  * raw messages, since the status return value is reserved for operational or
46  * logical error codes.
47  *
48  * Since PKCS#1 v1.5 padding is deterministic, we verify by re-encoding the
49  * message and comparing the result.
50  *
51  * @param message_digest Message digest to verify.
52  * @param encoded_message Encoded message.
53  * @param encoded_message_len Encoded message length in 32-bit words.
54  * @param[out] result True if the check passed.
55  * @return Result of the operation (OK or error).
56  */
58 status_t rsa_padding_pkcs1v15_verify(
59  const otcrypto_hash_digest_t message_digest,
60  const uint32_t *encoded_message, const size_t encoded_message_len,
61  hardened_bool_t *result);
62 
63 /**
64  * Encode the message with PSS encoding (RFC 8017, section 9.1.1).
65  *
66  * The caller must ensure that `encoded_message_len` 32-bit words are allocated
67  * in the output buffer.
68  *
69  * We encode the message in reversed byte-order from the RFC because OTBN
70  * interprets the message as a fully little-endian integer.
71  *
72  * @param message_digest Message digest to encode.
73  * @param salt Salt value.
74  * @param salt_len Length of the salt in 32-bit words.
75  * @param encoded_message_len Intended encoded message length in 32-bit words.
76  * @param[out] encoded_message Encoded message.
77  * @return Result of the operation (OK or error).
78  */
80 status_t rsa_padding_pss_encode(const otcrypto_hash_digest_t message_digest,
81  const uint32_t *salt, size_t salt_len,
82  size_t encoded_message_len,
83  uint32_t *encoded_message);
84 
85 /**
86  * Check if the PSS-encoded message represents the message.
87  *
88  * From RFC 8017, section 9.1.2. Assumes that the salt length always matches
89  * the digest length of the chosen hash function.
90  *
91  * If the encoded message does not match the message digest, this function will
92  * return an OK status and write `kHardenedBoolFalse` into the result buffer.
93  * The caller should not interpret an OK status as a match between the encoded
94  * and raw messages, since the status return value is reserved for operational
95  * or logical error codes.
96  *
97  * Note that this function expects the encoded message in reversed byte-order
98  * compared to the RFC, since OTBN is little-endian.
99  *
100  * Warning: modifies the encoded message in-place during comparison
101  * (specifically, reverses the byte-order).
102  *
103  * @param message_digest Message digest to verify.
104  * @param encoded_message Encoded message.
105  * @param encoded_message_len Encoded message length in 32-bit words.
106  * @param[out] result True if the check passed.
107  * @return Result of the operation (OK or error).
108  */
110 status_t rsa_padding_pss_verify(const otcrypto_hash_digest_t message_digest,
111  uint32_t *encoded_message,
112  size_t encoded_message_len,
113  hardened_bool_t *result);
114 
115 /**
116  * Maximum message byte-length for OAEP padding.
117  *
118  * As per RFC 8017, the maximum message byte-length for OAEP is k - 2*hLen - 2,
119  * where k is the size of the RSA modulus in bytes and hLen is the digest
120  * length of the hash function used for padding. This function provides a
121  * simple convenience interface so that callers can check that buffers for
122  * decoded messages are long enough.
123  *
124  * Returns an error if the hash mode is not supported (i.e., a non-fixed-length
125  * hash function).
126  *
127  * @param hash_mode Hash function to use for OAEP.
128  * @param rsa_wordlen RSA modulus size in 32-bit words.
129  * @param[out] max_message_bytelen Maximum length of message in bytes.
130  * @return Result of the operation (OK or error).
131  */
132 status_t rsa_padding_oaep_max_message_bytelen(
133  const otcrypto_hash_mode_t hash_mode, size_t rsa_wordlen,
134  size_t *max_message_bytelen);
135 
136 /**
137  * Encode the message with OAEP encoding (RFC 8017, section 7.1.1, steps 1-2).
138  *
139  * The caller must ensure that `encoded_message_len` 32-bit words are allocated
140  * in the output buffer.
141  *
142  * The maximum byte-length of the message (as per the RFC) is k - 2*hLen - 2,
143  * where k is the RSA size and hLen is the length of the hash digest. This
144  * function will return an error if the message is too long.
145  *
146  * The hash function must be a fixed-length (SHA-2 or SHA-3) hash function. The
147  * MGF will always be MGF1 with the same hash function.
148  *
149  * We encode the message in reversed byte-order from the RFC because OTBN
150  * interprets the message as a fully little-endian integer.
151  *
152  * @param hash_mode Hash function to use.
153  * @param message Message to encode.
154  * @param message_bytelen Message length in bytes.
155  * @param label Label for OAEP.
156  * @param label_bytelen Label length in bytes.
157  * @param encoded_message_len Intended encoded message length in 32-bit words.
158  * @param[out] encoded_message Encoded message.
159  * @return Result of the operation (OK or error).
160  */
162 status_t rsa_padding_oaep_encode(const otcrypto_hash_mode_t hash_mode,
163  const uint8_t *message, size_t message_bytelen,
164  const uint8_t *label, size_t label_bytelen,
165  size_t encoded_message_len,
166  uint32_t *encoded_message);
167 
168 /**
169  * Decode the OAEP-encoded message (RFC 8017, section 7.1.2, step 3).
170  *
171  * The maximum byte-length of the message (as per the RFC) is k - 2*hLen - 2,
172  * where k is the RSA size and hLen is the length of the hash digest. The
173  * caller must ensure there are at least this many bytes available for
174  * `message`; they can call `rsa_padding_oaep_max_message_bytelen` to get the
175  * exact value for a given hash mode and RSA size.
176  *
177  * The hash function must be a fixed-length (SHA-2 or SHA-3) hash function. The
178  * MGF will always be MGF1 with the same hash function.
179  *
180  * Note that this function expects the encoded message in reversed byte-order
181  * compared to the RFC, since OTBN is little-endian.
182  *
183  * Warning: modifies the encoded message in-place during comparison
184  * (specifically, reverses the byte-order).
185  *
186  * @param hash_mode Hash function to use.
187  * @param label Label for OAEP.
188  * @param label_bytelen Label length in bytes.
189  * @param encoded_message Encoded message.
190  * @param encoded_message_len Encoded message length in 32-bit words.
191  * @param[out] message Decoded message.
192  * @param[out] message_bytelen Length of the message in bytes.
193  * @return Result of the operation (OK or error).
194  */
196 status_t rsa_padding_oaep_decode(const otcrypto_hash_mode_t hash_mode,
197  const uint8_t *label, size_t label_bytelen,
198  uint32_t *encoded_message,
199  size_t encoded_message_len, uint8_t *message,
200  size_t *message_bytelen);
201 
202 #ifdef __cplusplus
203 } // extern "C"
204 #endif // __cplusplus
205 
206 #endif // OPENTITAN_SW_DEVICE_LIB_CRYPTO_IMPL_RSA_RSA_PADDING_H_