]> pd.if.org Git - zpackage/blob - libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / pk / pkcs1 / pkcs_1_v1_5_decode.c
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 /** @file pkcs_1_v1_5_decode.c
12  *
13  *  PKCS #1 v1.5 Padding. (Andreas Lange)
14  */
15
16 #ifdef LTC_PKCS_1
17
18 /** @brief PKCS #1 v1.5 decode.
19  *
20  *  @param msg              The encoded data to decode
21  *  @param msglen           The length of the encoded data (octets)
22  *  @param block_type       Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
23  *  @param modulus_bitlen   The bit length of the RSA modulus
24  *  @param out              [out] Destination of decoding
25  *  @param outlen           [in/out] The max size and resulting size of the decoding
26  *  @param is_valid         [out] Boolean whether the padding was valid
27  *
28  *  @return CRYPT_OK if successful
29  */
30 int pkcs_1_v1_5_decode(const unsigned char *msg,
31                              unsigned long  msglen,
32                                        int  block_type,
33                              unsigned long  modulus_bitlen,
34                              unsigned char *out,
35                              unsigned long *outlen,
36                                        int *is_valid)
37 {
38   unsigned long modulus_len, ps_len, i;
39   int result;
40
41   /* default to invalid packet */
42   *is_valid = 0;
43
44   modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
45
46   /* test message size */
47
48   if ((msglen > modulus_len) || (modulus_len < 11)) {
49     return CRYPT_PK_INVALID_SIZE;
50   }
51
52   result = CRYPT_OK;
53
54   /* separate encoded message */
55
56   if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) {
57     result = CRYPT_INVALID_PACKET;
58   }
59
60   if (block_type == LTC_PKCS_1_EME) {
61     for (i = 2; i < modulus_len; i++) {
62       /* separator */
63       if (msg[i] == 0x00) { break; }
64     }
65     ps_len = i++ - 2;
66
67     if (i >= modulus_len) {
68       /* There was no octet with hexadecimal value 0x00 to separate ps from m.
69        */
70       result = CRYPT_INVALID_PACKET;
71     }
72   } else {
73     for (i = 2; i < modulus_len - 1; i++) {
74        if (msg[i] != 0xFF) { break; }
75     }
76
77     /* separator check */
78     if (msg[i] != 0) {
79       /* There was no octet with hexadecimal value 0x00 to separate ps from m. */
80       result = CRYPT_INVALID_PACKET;
81     }
82
83     ps_len = i - 2;
84   }
85
86   if (ps_len < 8)
87   {
88     /* The length of ps is less than 8 octets.
89      */
90     result = CRYPT_INVALID_PACKET;
91   }
92
93   if (*outlen < (msglen - (2 + ps_len + 1))) {
94     result = CRYPT_INVALID_PACKET;
95   }
96
97   if (result == CRYPT_OK) {
98      *outlen = (msglen - (2 + ps_len + 1));
99      XMEMCPY(out, &msg[2 + ps_len + 1], *outlen);
100
101      /* valid packet */
102      *is_valid = 1;
103   }
104
105   return result;
106 } /* pkcs_1_v1_5_decode */
107
108 #endif /* #ifdef LTC_PKCS_1 */
109
110 /* ref:         $Format:%D$ */
111 /* git commit:  $Format:%H$ */
112 /* commit time: $Format:%ai$ */