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 (at) 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 $ */ 111