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_encode.c 14 * 15 * PKCS #1 v1.5 Padding (Andreas Lange) 16 */ 17 18 #ifdef PKCS_1 19 20 /*! \brief PKCS #1 v1.5 encode. 21 * 22 * \param msg The data to encode 23 * \param msglen The length of the data to encode (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 prng An active PRNG state (only for LTC_PKCS_1_EME) 27 * \param prng_idx The index of the PRNG desired (only for LTC_PKCS_1_EME) 28 * \param out [out] The destination for the encoded data 29 * \param outlen [in/out] The max size and resulting size of the encoded data 30 * 31 * \return CRYPT_OK if successful 32 */ 33 int pkcs_1_v1_5_encode(const unsigned char *msg, 34 unsigned long msglen, 35 int block_type, 36 unsigned long modulus_bitlen, 37 prng_state *prng, 38 int prng_idx, 39 unsigned char *out, 40 unsigned long *outlen) 41 { 42 unsigned long modulus_len, ps_len, i; 43 unsigned char *ps; 44 int result; 45 46 /* valid block_type? */ 47 if ((block_type != LTC_PKCS_1_EMSA) && 48 (block_type != LTC_PKCS_1_EME)) { 49 return CRYPT_PK_INVALID_PADDING; 50 } 51 52 if (block_type == LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */ 53 if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) { 54 return result; 55 } 56 } 57 58 modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); 59 60 /* test message size */ 61 if ((msglen + 11) > modulus_len) { 62 return CRYPT_PK_INVALID_SIZE; 63 } 64 65 if (*outlen < modulus_len) { 66 *outlen = modulus_len; 67 result = CRYPT_BUFFER_OVERFLOW; 68 goto bail; 69 } 70 71 /* generate an octets string PS */ 72 ps = &out[2]; 73 ps_len = modulus_len - msglen - 3; 74 75 if (block_type == LTC_PKCS_1_EME) { 76 /* now choose a random ps */ 77 if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) { 78 result = CRYPT_ERROR_READPRNG; 79 goto bail; 80 } 81 82 /* transform zero bytes (if any) to non-zero random bytes */ 83 for (i = 0; i < ps_len; i++) { 84 while (ps[i] == 0) { 85 if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) { 86 result = CRYPT_ERROR_READPRNG; 87 goto bail; 88 } 89 } 90 } 91 } else { 92 XMEMSET(ps, 0xFF, ps_len); 93 } 94 95 /* create string of length modulus_len */ 96 out[0] = 0x00; 97 out[1] = (unsigned char)block_type; /* block_type 1 or 2 */ 98 out[2 + ps_len] = 0x00; 99 XMEMCPY(&out[2 + ps_len + 1], msg, msglen); 100 *outlen = modulus_len; 101 102 result = CRYPT_OK; 103 bail: 104 return result; 105 } /* pkcs_1_v1_5_encode */ 106 107 #endif /* #ifdef PKCS_1 */ 108 109 /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c,v $ */ 110 /* $Revision: 1.2 $ */ 111 /* $Date: 2006/11/01 09:12:06 $ */ 112