Home | History | Annotate | Download | only in pkcs1
      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