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