1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /** @file pkcs_1_v1_5_decode.c
6 *
7 * PKCS #1 v1.5 Padding. (Andreas Lange)
8 */
9
10 #ifdef LTC_PKCS_1
11
12 /** @brief PKCS #1 v1.5 decode.
13 *
14 * @param msg The encoded data to decode
15 * @param msglen The length of the encoded data (octets)
16 * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
17 * @param modulus_bitlen The bit length of the RSA modulus
18 * @param out [out] Destination of decoding
19 * @param outlen [in/out] The max size and resulting size of the decoding
20 * @param is_valid [out] Boolean whether the padding was valid
21 *
22 * @return CRYPT_OK if successful
23 */
pkcs_1_v1_5_decode(const unsigned char * msg,unsigned long msglen,int block_type,unsigned long modulus_bitlen,unsigned char * out,unsigned long * outlen,int * is_valid)24 int pkcs_1_v1_5_decode(const unsigned char *msg,
25 unsigned long msglen,
26 int block_type,
27 unsigned long modulus_bitlen,
28 unsigned char *out,
29 unsigned long *outlen,
30 int *is_valid)
31 {
32 unsigned long modulus_len, ps_len, i;
33 int result;
34
35 /* default to invalid packet */
36 *is_valid = 0;
37
38 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
39
40 /* test message size */
41
42 if ((msglen > modulus_len) || (modulus_len < 11)) {
43 return CRYPT_PK_INVALID_SIZE;
44 }
45
46 result = CRYPT_OK;
47
48 /* separate encoded message */
49
50 if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) {
51 result = CRYPT_INVALID_PACKET;
52 }
53
54 if (block_type == LTC_PKCS_1_EME) {
55 for (i = 2; i < modulus_len; i++) {
56 /* separator */
57 if (msg[i] == 0x00) { break; }
58 }
59 ps_len = i++ - 2;
60
61 if (i >= modulus_len) {
62 /* There was no octet with hexadecimal value 0x00 to separate ps from m.
63 */
64 result = CRYPT_INVALID_PACKET;
65 }
66 } else {
67 for (i = 2; i < modulus_len - 1; i++) {
68 if (msg[i] != 0xFF) { break; }
69 }
70
71 /* separator check */
72 if (msg[i] != 0) {
73 /* There was no octet with hexadecimal value 0x00 to separate ps from m. */
74 result = CRYPT_INVALID_PACKET;
75 }
76
77 ps_len = i - 2;
78 }
79
80 if (ps_len < 8)
81 {
82 /* The length of ps is less than 8 octets.
83 */
84 result = CRYPT_INVALID_PACKET;
85 }
86
87 if (*outlen < (msglen - (2 + ps_len + 1))) {
88 result = CRYPT_INVALID_PACKET;
89 }
90
91 if (result == CRYPT_OK) {
92 *outlen = (msglen - (2 + ps_len + 1));
93 XMEMCPY(out, &msg[2 + ps_len + 1], *outlen);
94
95 /* valid packet */
96 *is_valid = 1;
97 }
98
99 return result;
100 } /* pkcs_1_v1_5_decode */
101
102 #endif /* #ifdef LTC_PKCS_1 */
103