2013-03-20 10:14:06 -07:00
|
|
|
/* crypto.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006-2013 wolfSSL Inc.
|
|
|
|
*
|
|
|
|
* This file is part of CyaSSL.
|
|
|
|
*
|
|
|
|
* CyaSSL is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* CyaSSL is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Implements Microchip CRYPTO API layer */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "crypto.h"
|
|
|
|
|
|
|
|
#include <cyassl/ctaocrypt/md5.h>
|
|
|
|
#include <cyassl/ctaocrypt/sha.h>
|
|
|
|
#include <cyassl/ctaocrypt/sha256.h>
|
|
|
|
#include <cyassl/ctaocrypt/sha512.h>
|
2013-03-20 11:59:27 -07:00
|
|
|
#include <cyassl/ctaocrypt/hmac.h>
|
2013-03-20 14:37:05 -07:00
|
|
|
#include <cyassl/ctaocrypt/compress.h>
|
2013-03-20 15:02:03 -07:00
|
|
|
#include <cyassl/ctaocrypt/random.h>
|
2013-03-20 18:35:26 -07:00
|
|
|
#include <cyassl/ctaocrypt/des3.h>
|
2013-03-20 19:21:04 -07:00
|
|
|
#include <cyassl/ctaocrypt/aes.h>
|
2013-03-20 10:14:06 -07:00
|
|
|
|
|
|
|
|
|
|
|
/* Initialize MD5 */
|
|
|
|
int CRYPT_MD5_Initialize(CRYPT_MD5_CTX* md5)
|
|
|
|
{
|
|
|
|
typedef char md5_test[sizeof(CRYPT_MD5_CTX) >= sizeof(Md5) ? 1 : -1];
|
|
|
|
(void)sizeof(md5_test);
|
|
|
|
|
|
|
|
InitMd5((Md5*)md5);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add data to MD5 */
|
|
|
|
int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
Md5Update((Md5*)md5, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get MD5 Final into digest */
|
|
|
|
int CRYPT_MD5_Finalize(CRYPT_MD5_CTX* md5, unsigned char* digest)
|
|
|
|
{
|
|
|
|
Md5Final((Md5*)md5, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize SHA */
|
|
|
|
int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha)
|
|
|
|
{
|
|
|
|
typedef char sha_test[sizeof(CRYPT_SHA_CTX) >= sizeof(Sha) ? 1 : -1];
|
|
|
|
(void)sizeof(sha_test);
|
|
|
|
|
|
|
|
InitSha((Sha*)sha);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add data to SHA */
|
|
|
|
int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX* sha, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
ShaUpdate((Sha*)sha, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get SHA Final into digest */
|
|
|
|
int CRYPT_SHA_Finalize(CRYPT_SHA_CTX* sha, unsigned char* digest)
|
|
|
|
{
|
|
|
|
ShaFinal((Sha*)sha, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize SHA-256 */
|
|
|
|
int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX* sha256)
|
|
|
|
{
|
|
|
|
typedef char sha_test[sizeof(CRYPT_SHA256_CTX) >= sizeof(Sha256) ? 1 : -1];
|
|
|
|
(void)sizeof(sha_test);
|
|
|
|
|
|
|
|
InitSha256((Sha256*)sha256);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add data to SHA-256 */
|
|
|
|
int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX* sha256, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
Sha256Update((Sha256*)sha256, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get SHA-256 Final into digest */
|
|
|
|
int CRYPT_SHA256_Finalize(CRYPT_SHA256_CTX* sha256, unsigned char* digest)
|
|
|
|
{
|
|
|
|
Sha256Final((Sha256*)sha256, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize SHA-384 */
|
|
|
|
int CRYPT_SHA384_Initialize(CRYPT_SHA384_CTX* sha384)
|
|
|
|
{
|
|
|
|
typedef char sha_test[sizeof(CRYPT_SHA384_CTX) >= sizeof(Sha384) ? 1 : -1];
|
|
|
|
(void)sizeof(sha_test);
|
|
|
|
|
|
|
|
InitSha384((Sha384*)sha384);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add data to SHA-384 */
|
|
|
|
int CRYPT_SHA384_DataAdd(CRYPT_SHA384_CTX* sha384, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
Sha384Update((Sha384*)sha384, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get SHA-384 Final into digest */
|
|
|
|
int CRYPT_SHA384_Finalize(CRYPT_SHA384_CTX* sha384, unsigned char* digest)
|
|
|
|
{
|
|
|
|
Sha384Final((Sha384*)sha384, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize SHA-512 */
|
|
|
|
int CRYPT_SHA512_Initialize(CRYPT_SHA512_CTX* sha512)
|
|
|
|
{
|
|
|
|
typedef char sha_test[sizeof(CRYPT_SHA512_CTX) >= sizeof(Sha512) ? 1 : -1];
|
|
|
|
(void)sizeof(sha_test);
|
|
|
|
|
|
|
|
InitSha512((Sha512*)sha512);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Add data to SHA-512 */
|
|
|
|
int CRYPT_SHA512_DataAdd(CRYPT_SHA512_CTX* sha512, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
Sha512Update((Sha512*)sha512, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get SHA-512 Final into digest */
|
|
|
|
int CRYPT_SHA512_Finalize(CRYPT_SHA512_CTX* sha512, unsigned char* digest)
|
|
|
|
{
|
|
|
|
Sha512Final((Sha512*)sha512, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 11:59:27 -07:00
|
|
|
/* Set HMAC key with type */
|
|
|
|
int CRYPT_HMAC_SetKey(CRYPT_HMAC_CTX* hmac, int type, const unsigned char* key,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
typedef char hmac_test[sizeof(CRYPT_HMAC_CTX) >= sizeof(Hmac) ? 1 : -1];
|
|
|
|
(void)sizeof(hmac_test);
|
|
|
|
|
|
|
|
if (type != CRYPT_HMAC_SHA && type != CRYPT_HMAC_SHA256 &&
|
|
|
|
type != CRYPT_HMAC_SHA384 && type != CRYPT_HMAC_SHA512) {
|
|
|
|
return -1; /* bad hmac type */
|
|
|
|
}
|
|
|
|
|
|
|
|
HmacSetKey((Hmac*)hmac, type, key, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int CRYPT_HMAC_DataAdd(CRYPT_HMAC_CTX* hmac, const unsigned char* input,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
HmacUpdate((Hmac*)hmac, input, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Get HMAC Final into digest */
|
|
|
|
int CRYPT_HMAC_Finalize(CRYPT_HMAC_CTX* hmac, unsigned char* digest)
|
|
|
|
{
|
|
|
|
HmacFinal((Hmac*)hmac, digest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 14:37:05 -07:00
|
|
|
/* Huffman Compression, set flag to do static, otherwise dynamic */
|
|
|
|
/* return compressed size, otherwise < 0 for error */
|
|
|
|
int CRYPT_HUFFMAN_Compress(unsigned char* out, unsigned int outSz,
|
|
|
|
const unsigned char* in, unsigned int inSz,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
return Compress(out, outSz, in, inSz, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Huffman DeCompression, self determines type */
|
|
|
|
/* return decompressed size, otherwise < 0 for error */
|
|
|
|
int CRYPT_HUFFMAN_DeCompress(unsigned char* out, unsigned int outSz,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
return DeCompress(out, outSz, in, inSz);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 15:02:03 -07:00
|
|
|
/* RNG Initialize, < 0 on error */
|
|
|
|
int CRYPT_RNG_Initialize(CRYPT_RNG_CTX* rng)
|
|
|
|
{
|
|
|
|
typedef char rng_test[sizeof(CRYPT_RNG_CTX) >= sizeof(RNG) ? 1 : -1];
|
|
|
|
(void)sizeof(rng_test);
|
|
|
|
|
|
|
|
return InitRng((RNG*)rng);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* RNG Get single bytes, < 0 on error */
|
|
|
|
int CRYPT_RNG_Get(CRYPT_RNG_CTX* rng, unsigned char* b)
|
|
|
|
{
|
|
|
|
*b = RNG_GenerateByte((RNG*)rng);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* RNG Block Generation of sz bytes, < 0 on error */
|
|
|
|
int CRYPT_RNG_BlockGenerate(CRYPT_RNG_CTX* rng, unsigned char* b,
|
|
|
|
unsigned int sz)
|
|
|
|
{
|
|
|
|
RNG_GenerateBlock((RNG*)rng, b, sz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 18:35:26 -07:00
|
|
|
/* Triple DES Key Set, may have iv, will have direction */
|
|
|
|
int CRYPT_TDES_KeySet(CRYPT_TDES_CTX* tdes, const unsigned char* key,
|
|
|
|
const unsigned char* iv, int dir)
|
|
|
|
{
|
|
|
|
typedef char tdes_test[sizeof(CRYPT_TDES_CTX) >= sizeof(Des3) ? 1 : -1];
|
|
|
|
(void)sizeof(tdes_test);
|
|
|
|
|
|
|
|
Des3_SetKey((Des3*)tdes, key, iv, dir);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Triple DES Iv Set, sometimes added later */
|
|
|
|
int CRYPT_TDES_IvSet(CRYPT_TDES_CTX* tdes, const unsigned char* iv)
|
|
|
|
{
|
|
|
|
Des3_SetIV((Des3*)tdes, iv);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Triple DES CBC Encrypt */
|
|
|
|
int CRYPT_TDES_CBC_Encrypt(CRYPT_TDES_CTX* tdes, unsigned char* out,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
Des3_CbcEncrypt((Des3*)tdes, out, in, inSz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Triple DES CBC Decrypt */
|
|
|
|
int CRYPT_TDES_CBC_Decrypt(CRYPT_TDES_CTX* tdes, unsigned char* out,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
Des3_CbcDecrypt((Des3*)tdes, out, in, inSz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-20 19:21:04 -07:00
|
|
|
/* AES Key Set, may have iv, will have direction */
|
|
|
|
int CRYPT_AES_KeySet(CRYPT_AES_CTX* aes, const unsigned char* key,
|
|
|
|
unsigned int keyLen, const unsigned char* iv, int dir)
|
|
|
|
{
|
|
|
|
typedef char aes_test[sizeof(CRYPT_AES_CTX) >= sizeof(Aes) ? 1 : -1];
|
|
|
|
(void)sizeof(aes_test);
|
|
|
|
|
|
|
|
return AesSetKey((Aes*)aes, key, keyLen, iv, dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* AES Iv Set, sometimes added later */
|
|
|
|
int CRYPT_AES_IvSet(CRYPT_AES_CTX* aes, const unsigned char* iv)
|
|
|
|
{
|
|
|
|
AesSetIV((Aes*)aes, iv);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-20 18:35:26 -07:00
|
|
|
|
2013-03-20 19:21:04 -07:00
|
|
|
/* AES CBC Encrypt */
|
|
|
|
int CRYPT_AES_CBC_Encrypt(CRYPT_AES_CTX* aes, unsigned char* out,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
AesCbcEncrypt((Aes*)aes, out, in, inSz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* AES CBC Decrypt */
|
|
|
|
int CRYPT_AES_CBC_Decrypt(CRYPT_AES_CTX* aes, unsigned char* out,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
AesCbcDecrypt((Aes*)aes, out, in, inSz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2013-03-20 18:35:26 -07:00
|
|
|
|
2013-03-20 15:02:03 -07:00
|
|
|
|
2013-03-21 08:33:02 -07:00
|
|
|
/* AES CTR Encrypt (used for decrypt too, with ENCRYPT key setup) */
|
|
|
|
int CRYPT_AES_CTR_Encrypt(CRYPT_AES_CTX* aes, unsigned char* out,
|
|
|
|
const unsigned char* in, unsigned int inSz)
|
|
|
|
{
|
|
|
|
AesCtrEncrypt((Aes*)aes, out, in, inSz);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-03-20 15:02:03 -07:00
|
|
|
|
|
|
|
|