mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 15:38:14 +08:00
修改了Web后台的部分界面,增加了HAmqtt中的总电量传感器,后台新增mqtt上报频率设置
This commit is contained in:
871
mico-os/libraries/utilities/AESUtils.c
Normal file
871
mico-os/libraries/utilities/AESUtils.c
Normal file
@@ -0,0 +1,871 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file AESUtils.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file contains functiond called by the MICO project.
|
||||
* These functions abstract the interaction with AES libraries.
|
||||
******************************************************************************
|
||||
*
|
||||
* The MIT License
|
||||
* Copyright (c) 2014 MXCHIP Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "AESUtils.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
#include <CommonCrypto/CommonCryptorSPI.h>
|
||||
#endif
|
||||
|
||||
#if( !AES_UTILS_USE_COMMON_CRYPTO && !AES_UTILS_USE_GLADMAN_AES && TARGET_NO_OPENSSL )
|
||||
static
|
||||
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const unsigned long length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc);
|
||||
#endif
|
||||
|
||||
#define aes_log(M, ...) custom_log("AES", M, ##__VA_ARGS__)
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CTR_Init
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus
|
||||
AES_CTR_Init(
|
||||
AES_CTR_Context * inContext,
|
||||
const uint8_t inKey[ kAES_CTR_Size ],
|
||||
const uint8_t inNonce[ kAES_CTR_Size ] )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
OSStatus err;
|
||||
|
||||
inContext->cryptor = NULL;
|
||||
err = CCCryptorCreate( kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode, inKey, kAES_CTR_Size, NULL,
|
||||
&inContext->cryptor );
|
||||
check_noerr( err );
|
||||
if( err ) return( err );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
aes_init();
|
||||
aes_encrypt_key128( inKey, &inContext->ctx );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesSetKeyDirect(&inContext->ctx, (unsigned char *) inKey, AES_BLOCK_SIZE, inNonce, AES_ENCRYPTION);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
aes_setkey_enc( &inContext->ctx, (unsigned char *) inKey, kAES_CTR_Size * 8 );
|
||||
#else
|
||||
AES_set_encrypt_key( inKey, kAES_CTR_Size * 8, &inContext->key );
|
||||
#endif
|
||||
memcpy( inContext->ctr, inNonce, kAES_CTR_Size );
|
||||
inContext->used = 0;
|
||||
inContext->legacy = false;
|
||||
return( kNoErr );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CTR_Increment
|
||||
//===========================================================================================================================
|
||||
|
||||
static inline void AES_CTR_Increment( uint8_t *inCounter )
|
||||
{
|
||||
int i;
|
||||
|
||||
// Note: counter is always big endian so this adds from right to left.
|
||||
|
||||
for( i = kAES_CTR_Size - 1; i >= 0; --i )
|
||||
{
|
||||
if( ++( inCounter[ i ] ) != 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CTR_Update
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus AES_CTR_Update( AES_CTR_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
const uint8_t * src;
|
||||
uint8_t * dst;
|
||||
uint8_t * buf;
|
||||
size_t used;
|
||||
size_t i;
|
||||
|
||||
// inSrc and inDst may be the same, but otherwise, the buffers must not overlap.
|
||||
|
||||
#if( DEBUG )
|
||||
if( inSrc != inDst ) check_ptr_overlap( inSrc, inLen, inDst, inLen );
|
||||
#endif
|
||||
|
||||
src = (const uint8_t *) inSrc;
|
||||
dst = (uint8_t *) inDst;
|
||||
|
||||
// If there's any buffered key material from a previous block then use that first.
|
||||
|
||||
buf = inContext->buf;
|
||||
used = inContext->used;
|
||||
while( ( inLen > 0 ) && ( used != 0 ) )
|
||||
{
|
||||
*dst++ = *src++ ^ buf[ used++ ];
|
||||
used %= kAES_CTR_Size;
|
||||
inLen -= 1;
|
||||
}
|
||||
inContext->used = used;
|
||||
|
||||
// Process whole blocks.
|
||||
|
||||
while( inLen >= kAES_CTR_Size )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorUpdate( inContext->cryptor, inContext->ctr, kAES_CTR_Size, buf, kAES_CTR_Size, &i );
|
||||
require_noerr( err, exit );
|
||||
require_action( i == kAES_CTR_Size, exit, err = kSizeErr );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
aes_ecb_encrypt( inContext->ctr, buf, kAES_CTR_Size, &inContext->ctx );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesEncryptDirect( &inContext->ctx, buf, inContext->ctr );
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
aes_crypt_ecb( &inContext->ctx, AES_ENCRYPT, inContext->ctr, buf );
|
||||
#else
|
||||
AES_encrypt( inContext->ctr, buf, &inContext->key );
|
||||
#endif
|
||||
AES_CTR_Increment( inContext->ctr );
|
||||
|
||||
for( i = 0; i < kAES_CTR_Size; ++i )
|
||||
{
|
||||
dst[ i ] = src[ i ] ^ buf[ i ];
|
||||
}
|
||||
src += kAES_CTR_Size;
|
||||
dst += kAES_CTR_Size;
|
||||
inLen -= kAES_CTR_Size;
|
||||
}
|
||||
|
||||
// Process any trailing sub-block bytes. Extra key material is buffered for next time.
|
||||
|
||||
if( inLen > 0 )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorUpdate( inContext->cryptor, inContext->ctr, kAES_CTR_Size, buf, kAES_CTR_Size, &i );
|
||||
require_noerr( err, exit );
|
||||
require_action( i == kAES_CTR_Size, exit, err = kSizeErr );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
aes_ecb_encrypt( inContext->ctr, buf, kAES_CTR_Size, &inContext->ctx );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesEncryptDirect( &inContext->ctx, buf, inContext->ctr );
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
aes_crypt_ecb( &inContext->ctx, AES_ENCRYPT, inContext->ctr, buf );
|
||||
#else
|
||||
AES_encrypt( inContext->ctr, buf, &inContext->key );
|
||||
#endif
|
||||
AES_CTR_Increment( inContext->ctr );
|
||||
|
||||
for( i = 0; i < inLen; ++i )
|
||||
{
|
||||
*dst++ = *src++ ^ buf[ used++ ];
|
||||
}
|
||||
|
||||
// For legacy mode, always leave the used amount as 0 so we always increment the counter each time.
|
||||
|
||||
if( !inContext->legacy )
|
||||
{
|
||||
inContext->used = used;
|
||||
}
|
||||
}
|
||||
err = kNoErr;
|
||||
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
exit:
|
||||
#endif
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CTR_Final
|
||||
//===========================================================================================================================
|
||||
|
||||
void AES_CTR_Final( AES_CTR_Context *inContext )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
|
||||
#endif
|
||||
memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CBCFrame_Init
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus
|
||||
AES_CBCFrame_Init(
|
||||
AES_CBCFrame_Context * inContext,
|
||||
const uint8_t inKey[ kAES_CBCFrame_Size ],
|
||||
const uint8_t inIV[ kAES_CBCFrame_Size ],
|
||||
Boolean inEncrypt )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
OSStatus err;
|
||||
|
||||
inContext->cryptor = NULL;
|
||||
err = CCCryptorCreate( inEncrypt ? kCCEncrypt : kCCDecrypt, kCCAlgorithmAES128, 0, inKey, kAES_CTR_Size,
|
||||
NULL, &inContext->cryptor );
|
||||
check_noerr( err );
|
||||
if( err ) return( err );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
aes_init();
|
||||
if( inEncrypt ) aes_encrypt_key128( inKey, &inContext->ctx.encrypt );
|
||||
else aes_decrypt_key128( inKey, &inContext->ctx.decrypt );
|
||||
inContext->encrypt = inEncrypt;
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
if( inEncrypt ) AesSetKeyDirect(&inContext->ctx, (unsigned char *) inKey, AES_BLOCK_SIZE, inIV, AES_ENCRYPTION);
|
||||
else AesSetKeyDirect(&inContext->ctx, (unsigned char *) inKey, AES_BLOCK_SIZE, inIV, AES_DECRYPTION);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
if( inEncrypt ) aes_setkey_enc( &inContext->ctx, (unsigned char *) inKey, kAES_CBCFrame_Size * 8 );
|
||||
else aes_setkey_dec( &inContext->ctx, (unsigned char *) inKey, kAES_CBCFrame_Size * 8 );
|
||||
inContext->encrypt = inEncrypt;
|
||||
#else
|
||||
if( inEncrypt ) AES_set_encrypt_key( inKey, kAES_CBCFrame_Size * 8, &inContext->key );
|
||||
else AES_set_decrypt_key( inKey, kAES_CBCFrame_Size * 8, &inContext->key );
|
||||
inContext->mode = inEncrypt ? AES_ENCRYPT : AES_DECRYPT;
|
||||
#endif
|
||||
memcpy( inContext->iv, inIV, kAES_CBCFrame_Size );
|
||||
return( kNoErr );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CBCFrame_Update
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus AES_CBCFrame_Update( AES_CBCFrame_Context *inContext, const void *inSrc, size_t inSrcLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
const uint8_t * src;
|
||||
const uint8_t * end;
|
||||
uint8_t * dst;
|
||||
size_t len;
|
||||
|
||||
src = (const uint8_t *) inSrc;
|
||||
end = src + inSrcLen;
|
||||
dst = (uint8_t *) inDst;
|
||||
|
||||
// Process whole blocks.
|
||||
|
||||
len = inSrcLen & ~( (size_t)( kAES_CBCFrame_Size - 1 ) );
|
||||
if( len > 0 )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorReset( inContext->cryptor, inContext->iv );
|
||||
require_noerr( err, exit );
|
||||
|
||||
err = CCCryptorUpdate( inContext->cryptor, src, len, dst, len, &len );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
uint8_t iv[ kAES_CBCFrame_Size ];
|
||||
|
||||
memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed.
|
||||
if( inContext->encrypt ) aes_cbc_encrypt( src, dst, (int) len, iv, &inContext->ctx.encrypt );
|
||||
else aes_cbc_decrypt( src, dst, (int) len, iv, &inContext->ctx.decrypt );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesCbcEncrypt(&inContext->ctx, dst, src, len);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
uint8_t iv[ kAES_CBCFrame_Size ];
|
||||
|
||||
memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed.
|
||||
if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src, dst );
|
||||
else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src, dst );
|
||||
#else
|
||||
uint8_t iv[ kAES_CBCFrame_Size ];
|
||||
|
||||
memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed.
|
||||
AES_cbc_encrypt( src, dst, (unsigned long) len, &inContext->key, iv, inContext->mode );
|
||||
#endif
|
||||
src += len;
|
||||
dst += len;
|
||||
}
|
||||
|
||||
// The remaining bytes are just copied unencrypted.
|
||||
|
||||
while( src != end ) *dst++ = *src++;
|
||||
err = kNoErr;
|
||||
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
exit:
|
||||
#endif
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CBCFrame_Update2
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus
|
||||
AES_CBCFrame_Update2(
|
||||
AES_CBCFrame_Context * inContext,
|
||||
const void * inSrc1,
|
||||
size_t inLen1,
|
||||
const void * inSrc2,
|
||||
size_t inLen2,
|
||||
void * inDst )
|
||||
{
|
||||
const uint8_t * src1 = (const uint8_t *) inSrc1;
|
||||
const uint8_t * end1 = src1 + inLen1;
|
||||
const uint8_t * src2 = (const uint8_t *) inSrc2;
|
||||
const uint8_t * end2 = src2 + inLen2;
|
||||
uint8_t * dst = (uint8_t *) inDst;
|
||||
OSStatus err;
|
||||
size_t len;
|
||||
size_t i;
|
||||
#if( !AES_UTILS_USE_COMMON_CRYPTO )
|
||||
uint8_t iv[ kAES_CBCFrame_Size ];
|
||||
#endif
|
||||
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
if( ( inLen1 + inLen2 ) >= kAES_CBCFrame_Size )
|
||||
{
|
||||
err = CCCryptorReset( inContext->cryptor, inContext->iv );
|
||||
require_noerr( err, exit );
|
||||
}
|
||||
#else
|
||||
memcpy( iv, inContext->iv, kAES_CBCFrame_Size ); // Use local copy so original IV is not changed.
|
||||
#endif
|
||||
|
||||
// Process all whole blocks from buffer 1.
|
||||
|
||||
len = inLen1 & ~( (size_t)( kAES_CBCFrame_Size - 1 ) );
|
||||
if( len > 0 )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorUpdate( inContext->cryptor, src1, len, dst, len, &len );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
if( inContext->encrypt ) aes_cbc_encrypt( src1, dst, (int) len, iv, &inContext->ctx.encrypt );
|
||||
else aes_cbc_decrypt( src1, dst, (int) len, iv, &inContext->ctx.decrypt );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesCbcEncrypt(&inContext->ctx, dst, src1, len);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src1, dst );
|
||||
else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src1, dst );
|
||||
#else
|
||||
AES_cbc_encrypt( src1, dst, (unsigned long) len, &inContext->key, iv, inContext->mode );
|
||||
#endif
|
||||
src1 += len;
|
||||
dst += len;
|
||||
}
|
||||
|
||||
// If there are any partial block bytes in buffer 1 and enough bytes in buffer 2 to fill a
|
||||
// block then combine them into a temporary buffer and encrypt it.
|
||||
|
||||
if( ( src1 != end1 ) && ( ( ( end1 - src1 ) + ( end2 - src2 ) ) >= kAES_CBCFrame_Size ) )
|
||||
{
|
||||
uint8_t buf[ kAES_CBCFrame_Size ];
|
||||
|
||||
for( i = 0; src1 != end1; ++i )
|
||||
{
|
||||
buf[ i ] = *src1++;
|
||||
}
|
||||
for( ; ( i < kAES_CBCFrame_Size ) && ( src2 != end2 ); ++i )
|
||||
{
|
||||
buf[ i ] = *src2++;
|
||||
}
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorUpdate( inContext->cryptor, buf, i, dst, i, &i );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
if( inContext->encrypt ) aes_cbc_encrypt( buf, dst, (int) i, iv, &inContext->ctx.encrypt );
|
||||
else aes_cbc_decrypt( buf, dst, (int) i, iv, &inContext->ctx.decrypt );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesCbcEncrypt(&inContext->ctx, dst, buf, i);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, i, iv, buf, dst );
|
||||
else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, i, iv, buf, dst );
|
||||
#else
|
||||
AES_cbc_encrypt( buf, dst, (unsigned long) i, &inContext->key, iv, inContext->mode );
|
||||
#endif
|
||||
dst += i;
|
||||
}
|
||||
|
||||
// Process any remaining whole blocks in buffer 2.
|
||||
|
||||
len = ( (size_t)( end2 - src2 ) ) & ~( (size_t)( kAES_CBCFrame_Size - 1 ) );
|
||||
if( len > 0 )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
err = CCCryptorUpdate( inContext->cryptor, src2, len, dst, len, &len );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
if( inContext->encrypt ) aes_cbc_encrypt( src2, dst, (int) len, iv, &inContext->ctx.encrypt );
|
||||
else aes_cbc_decrypt( src2, dst, (int) len, iv, &inContext->ctx.decrypt );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesCbcEncrypt(&inContext->ctx, dst, src2, len);
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
if( inContext->encrypt ) aes_crypt_cbc( &inContext->ctx, AES_ENCRYPT, len, iv, (unsigned char *) src2, dst );
|
||||
else aes_crypt_cbc( &inContext->ctx, AES_DECRYPT, len, iv, (unsigned char *) src2, dst );
|
||||
#else
|
||||
AES_cbc_encrypt( src2, dst, (unsigned long) len, &inContext->key, iv, inContext->mode );
|
||||
#endif
|
||||
src2 += len;
|
||||
dst += len;
|
||||
}
|
||||
|
||||
// Any remaining bytes are just copied unencrypted.
|
||||
|
||||
while( src1 != end1 ) *dst++ = *src1++;
|
||||
while( src2 != end2 ) *dst++ = *src2++;
|
||||
err = kNoErr;
|
||||
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
exit:
|
||||
#endif
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_CBCFrame_Final
|
||||
//===========================================================================================================================
|
||||
|
||||
void AES_CBCFrame_Final( AES_CBCFrame_Context *inContext )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
|
||||
#endif
|
||||
memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_cbc_encrypt
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( !AES_UTILS_USE_COMMON_CRYPTO && !AES_UTILS_USE_GLADMAN_AES && !AES_UTILS_USE_MICO_AES && TARGET_NO_OPENSSL )
|
||||
// From OpenSSL
|
||||
static
|
||||
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const unsigned long length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc) {
|
||||
|
||||
unsigned long n;
|
||||
unsigned long len = length;
|
||||
unsigned char tmp[AES_BLOCK_SIZE];
|
||||
const unsigned char *iv = ivec;
|
||||
|
||||
if (AES_ENCRYPT == enc) {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
iv = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
for(n=len; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
iv = out;
|
||||
}
|
||||
memcpy(ivec,iv,AES_BLOCK_SIZE);
|
||||
} else if (in != out) {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
AES_decrypt(in, out, key);
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
iv = in;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
AES_decrypt(in,tmp,key);
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] = tmp[n] ^ iv[n];
|
||||
iv = in;
|
||||
}
|
||||
memcpy(ivec,iv,AES_BLOCK_SIZE);
|
||||
} else {
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(in, out, key);
|
||||
for(n=0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
memcpy(ivec, tmp, AES_BLOCK_SIZE);
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (len) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(tmp, out, key);
|
||||
for(n=0; n < len; ++n)
|
||||
out[n] ^= ivec[n];
|
||||
for(n=len; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = tmp[n];
|
||||
memcpy(ivec, tmp, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_ECB_Init
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus AES_ECB_Init( AES_ECB_Context *inContext, uint32_t inMode, const uint8_t inKey[ kAES_ECB_Size ] )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
OSStatus err;
|
||||
|
||||
inContext->cryptor = NULL;
|
||||
err = CCCryptorCreate( inMode, kCCAlgorithmAES128, kCCOptionECBMode, inKey, kAES_ECB_Size, NULL, &inContext->cryptor );
|
||||
check_noerr( err );
|
||||
if( err ) return( err );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
aes_init();
|
||||
if( inMode == kAES_ECB_Mode_Encrypt ) aes_encrypt_key128( inKey, &inContext->ctx.encrypt );
|
||||
else aes_decrypt_key128( inKey, &inContext->ctx.decrypt );
|
||||
inContext->encrypt = inMode;
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
if( inMode == kAES_ECB_Mode_Encrypt ) AesSetKey( &inContext->ctx, inKey, kAES_ECB_Size, NULL, AES_ENCRYPTION );
|
||||
else AesSetKey( &inContext->ctx, inKey, kAES_ECB_Size, NULL, AES_DECRYPTION );
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
if( inMode == kAES_ECB_Mode_Encrypt ) aes_setkey_enc( &inContext->ctx, (unsigned char *) inKey, kAES_ECB_Size * 8 );
|
||||
else aes_setkey_dec( &inContext->ctx, (unsigned char *) inKey, kAES_ECB_Size * 8 );
|
||||
inContext->mode = inMode;
|
||||
#else
|
||||
AES_set_encrypt_key( inKey, kAES_ECB_Size * 8, &inContext->key );
|
||||
inContext->cryptFunc = ( inMode == kAES_ECB_Mode_Encrypt ) ? AES_encrypt : AES_decrypt;
|
||||
#endif
|
||||
return( kNoErr );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_ECB_Update
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus AES_ECB_Update( AES_ECB_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
const uint8_t * src;
|
||||
uint8_t * dst;
|
||||
size_t n;
|
||||
|
||||
// inSrc and inDst may be the same, but otherwise, the buffers must not overlap.
|
||||
|
||||
#if( DEBUG )
|
||||
if( inSrc != inDst ) check_ptr_overlap( inSrc, inLen, inDst, inLen );
|
||||
if( ( inLen % kAES_ECB_Size ) != 0 ) aes_log( "ECB doesn't support non-block-sized operations (%d bytes)", (int)inLen );
|
||||
#endif
|
||||
|
||||
src = (const uint8_t *) inSrc;
|
||||
dst = (uint8_t *) inDst;
|
||||
for( n = inLen / kAES_ECB_Size; n > 0; --n )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
size_t len;
|
||||
|
||||
err = CCCryptorUpdate( inContext->cryptor, src, kAES_ECB_Size, dst, kAES_ECB_Size, &len );
|
||||
require_noerr( err, exit );
|
||||
check( len == kAES_ECB_Size );
|
||||
#elif( AES_UTILS_USE_GLADMAN_AES )
|
||||
if( inContext->encrypt ) aes_ecb_encrypt( src, dst, kAES_ECB_Size, &inContext->ctx.encrypt );
|
||||
else aes_ecb_decrypt( src, dst, kAES_ECB_Size, &inContext->ctx.decrypt );
|
||||
#elif( AES_UTILS_USE_MICO_AES )
|
||||
AesEncryptDirect( &inContext->ctx, dst, src );
|
||||
#elif( AES_UTILS_USE_USSL )
|
||||
aes_crypt_ecb( &inContext->ctx, inContext->mode, (unsigned char *) src, dst );
|
||||
#else
|
||||
inContext->cryptFunc( src, dst, &inContext->key );
|
||||
#endif
|
||||
src += kAES_ECB_Size;
|
||||
dst += kAES_ECB_Size;
|
||||
}
|
||||
err = kNoErr;
|
||||
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
exit:
|
||||
#endif
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_ECB_Final
|
||||
//===========================================================================================================================
|
||||
|
||||
void AES_ECB_Final( AES_ECB_Context *inContext )
|
||||
{
|
||||
#if( AES_UTILS_USE_COMMON_CRYPTO )
|
||||
if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
|
||||
#endif
|
||||
memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
#if( AES_UTILS_HAS_GCM )
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_Init
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus
|
||||
AES_GCM_Init(
|
||||
AES_GCM_Context * inContext,
|
||||
const uint8_t inKey[ kAES_CGM_Size ],
|
||||
const uint8_t inNonce[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
err = CCCryptorCreateWithMode( kCCEncrypt, kCCModeGCM, kCCAlgorithmAES128, ccNoPadding, NULL,
|
||||
inKey, kAES_CGM_Size, NULL, 0, 0, 0, &inContext->cryptor );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
err = gcm_init_and_key( inKey, kAES_CGM_Size, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
#else
|
||||
#error "GCM enabled, but no implementation?"
|
||||
#endif
|
||||
|
||||
if( inNonce ) memcpy( inContext->nonce, inNonce, kAES_CGM_Size );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_Final
|
||||
//===========================================================================================================================
|
||||
|
||||
void AES_GCM_Final( AES_GCM_Context *inContext )
|
||||
{
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
if( inContext->cryptor ) CCCryptorRelease( inContext->cryptor );
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
gcm_end( &inContext->ctx );
|
||||
#else
|
||||
#error "GCM enabled, but no implementation?"
|
||||
#endif
|
||||
memset( inContext, 0, sizeof( *inContext ) ); // Clear sensitive data.
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_InitMessage
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
OSStatus AES_GCM_InitMessage( AES_GCM_Context *inContext, const uint8_t inNonce[ kAES_CGM_Size ] )
|
||||
{
|
||||
CCCryptorRef const cryptor = inContext->cryptor;
|
||||
OSStatus err;
|
||||
|
||||
err = CCCryptorGCMReset( cryptor );
|
||||
require_noerr( err, exit );
|
||||
|
||||
if( inNonce == kAES_CGM_Nonce_Auto )
|
||||
{
|
||||
AES_CTR_Increment( inContext->nonce );
|
||||
inNonce = inContext->nonce;
|
||||
}
|
||||
err = CCCryptorGCMAddIV( cryptor, inNonce, kAES_CGM_Size );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
OSStatus AES_GCM_InitMessage( AES_GCM_Context *inContext, const uint8_t inNonce[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
if( inNonce == kAES_CGM_Nonce_Auto )
|
||||
{
|
||||
AES_CTR_Increment( inContext->nonce );
|
||||
inNonce = inContext->nonce;
|
||||
}
|
||||
err = gcm_init_message( inNonce, kAES_CGM_Size, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_FinalizeMessage
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
OSStatus AES_GCM_FinalizeMessage( AES_GCM_Context *inContext, uint8_t outAuthTag[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
size_t len;
|
||||
|
||||
len = kAES_CGM_Size;
|
||||
err = CCCryptorGCMFinal( inContext->cryptor, outAuthTag, &len );
|
||||
require_noerr( err, exit );
|
||||
require_action( len == kAES_CGM_Size, exit, err = kSizeErr );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
OSStatus AES_GCM_FinalizeMessage( AES_GCM_Context *inContext, uint8_t outAuthTag[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = gcm_compute_tag( outAuthTag, kAES_CGM_Size, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_VerifyMessage
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
OSStatus AES_GCM_VerifyMessage( AES_GCM_Context *inContext, const uint8_t inAuthTag[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
size_t len;
|
||||
uint8_t authTag[ kAES_CGM_Size ];
|
||||
|
||||
len = kAES_CGM_Size;
|
||||
err = CCCryptorGCMFinal( inContext->cryptor, authTag, &len );
|
||||
require_noerr( err, exit );
|
||||
require_action( len == kAES_CGM_Size, exit, err = kSizeErr );
|
||||
require_action_quiet( memcmp_constant_time( authTag, inAuthTag, len ) == 0, exit, err = kAuthenticationErr );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
OSStatus AES_GCM_VerifyMessage( AES_GCM_Context *inContext, const uint8_t inAuthTag[ kAES_CGM_Size ] )
|
||||
{
|
||||
OSStatus err;
|
||||
uint8_t authTag[ kAES_CGM_Size ];
|
||||
|
||||
err = gcm_compute_tag( authTag, kAES_CGM_Size, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
require_action_quiet( memcmp_constant_time( authTag, inAuthTag, kAES_CGM_Size ) == 0, exit, err = kAuthenticationErr );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_AddAAD
|
||||
//===========================================================================================================================
|
||||
|
||||
OSStatus AES_GCM_AddAAD( AES_GCM_Context *inContext, const void *inPtr, size_t inLen )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
err = CCCryptorGCMaddAAD( inContext->cryptor, inPtr, inLen );
|
||||
require_noerr( err, exit );
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
err = gcm_auth_header( inPtr, inLen, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
#else
|
||||
#error "GCM enabled, but no implementation?"
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_Encrypt
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
OSStatus AES_GCM_Encrypt( AES_GCM_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = CCCryptorGCMEncrypt( inContext->cryptor, inSrc, inLen, inDst );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
OSStatus AES_GCM_Encrypt( AES_GCM_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = gcm_encrypt( inDst, inSrc, inLen, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================================================================
|
||||
// AES_GCM_Decrypt
|
||||
//===========================================================================================================================
|
||||
|
||||
#if( AES_UTILS_HAS_COMMON_CRYPTO_GCM )
|
||||
OSStatus AES_GCM_Decrypt( AES_GCM_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = CCCryptorGCMDecrypt( inContext->cryptor, inSrc, inLen, inDst );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#elif( AES_UTILS_HAS_GLADMAN_GCM )
|
||||
OSStatus AES_GCM_Decrypt( AES_GCM_Context *inContext, const void *inSrc, size_t inLen, void *inDst )
|
||||
{
|
||||
OSStatus err;
|
||||
|
||||
err = gcm_decrypt( inDst, inSrc, inLen, &inContext->ctx );
|
||||
require_noerr( err, exit );
|
||||
|
||||
exit:
|
||||
return( err );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user