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