|
|
@@ -9,7 +9,29 @@ |
|
|
|
#include <openssl/err.h> |
|
|
|
#include "pkcs7.h" |
|
|
|
|
|
|
|
static Result_t crypt( CryptoAttribs_t* attribs, |
|
|
|
void process_block(uint8_t in[16], uint8_t out[16], const Key_t* const key, bool encrypt) |
|
|
|
{ |
|
|
|
int ret; |
|
|
|
|
|
|
|
EVP_CIPHER_CTX ctx; |
|
|
|
EVP_CIPHER_CTX_init(&ctx); |
|
|
|
OP_CHECK( |
|
|
|
EVP_CipherInit_ex( &ctx, EVP_aes_128_ecb(), NULL, key->key, NULL, encrypt)); |
|
|
|
OP_CHECK( EVP_CIPHER_CTX_iv_length(&ctx) == 0); |
|
|
|
EVP_CIPHER_CTX_set_padding(&ctx, 0); |
|
|
|
OP_CHECK( EVP_CipherUpdate(&ctx, out, &ret, in, 16)); |
|
|
|
if(ret != 16) { |
|
|
|
printf("ERROR %d %lu \n", ret, 16); |
|
|
|
} |
|
|
|
OP_CHECK( EVP_CipherFinal_ex(&ctx, out+ret, &ret)); |
|
|
|
if(ret != 0) { |
|
|
|
printf("ERROR %d %lu \n", ret, 16); |
|
|
|
} |
|
|
|
end: |
|
|
|
EVP_CIPHER_CTX_cleanup(&ctx); |
|
|
|
} |
|
|
|
|
|
|
|
Result_t aes_whole_blocks( CryptoAttribs_t* attribs, |
|
|
|
const Key_t* const key) |
|
|
|
{ |
|
|
|
assert(key != NULL); |
|
|
@@ -22,34 +44,14 @@ static Result_t crypt( CryptoAttribs_t* attribs, |
|
|
|
{ |
|
|
|
attribs->output = (uint8_t*) malloc(max_size+1/* +1 because it's needed in final */); |
|
|
|
} |
|
|
|
int ret = 0; |
|
|
|
EVP_CIPHER_CTX ctx; |
|
|
|
EVP_CIPHER_CTX_init(&ctx); |
|
|
|
|
|
|
|
OP_CHECK( |
|
|
|
EVP_CipherInit_ex( &ctx, EVP_aes_128_ecb(), NULL, key->key, NULL, |
|
|
|
(attribs->operation == kEncrypt ? 1 : 0)) ); |
|
|
|
OP_CHECK( EVP_CIPHER_CTX_iv_length(&ctx) == 0); |
|
|
|
EVP_CIPHER_CTX_set_padding(&ctx, 0); |
|
|
|
OP_CHECK( EVP_CipherUpdate(&ctx, attribs->output, &ret, attribs->input, attribs->input_len) ); |
|
|
|
attribs->output_len += ret; |
|
|
|
if(ret > max_size ) |
|
|
|
{ |
|
|
|
printf("ERROR %d %lu \n", ret, attribs->output_len); |
|
|
|
res = Result_Error; |
|
|
|
goto end; |
|
|
|
} |
|
|
|
OP_CHECK( EVP_CipherFinal_ex(&ctx, &attribs->output[ret], &ret) ); |
|
|
|
attribs->output_len += ret; |
|
|
|
if(attribs->output_len > max_size ) |
|
|
|
{ |
|
|
|
printf("ERROR %d %lu \n", ret, attribs->output_len); |
|
|
|
res = Result_Error; |
|
|
|
goto end; |
|
|
|
unsigned blocks = attribs->input_len / 16; |
|
|
|
for(unsigned i=0; i<blocks; i++) { |
|
|
|
process_block(attribs->input+(i*16), attribs->output+attribs->output_len, key, attribs->operation == kEncrypt); |
|
|
|
attribs->output_len += 16; |
|
|
|
} |
|
|
|
|
|
|
|
end: |
|
|
|
EVP_CIPHER_CTX_cleanup(&ctx); |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
@@ -95,7 +97,7 @@ Result_t cbc_decrypt( |
|
|
|
|
|
|
|
// 1. Decrypt |
|
|
|
ecb_attribs.operation = kDecrypt; |
|
|
|
if( crypt(&ecb_attribs, key) != Result_OK ) |
|
|
|
if( aes_whole_blocks(&ecb_attribs, key) != Result_OK ) |
|
|
|
return Result_Error; |
|
|
|
|
|
|
|
// 2. Xor IV |
|
|
@@ -188,7 +190,7 @@ Result_t cbc_encrypt( |
|
|
|
|
|
|
|
// 2. Encrypt |
|
|
|
ecb_attribs.operation = kEncrypt; |
|
|
|
if( crypt(&ecb_attribs, key) != Result_OK ) |
|
|
|
if( aes_whole_blocks(&ecb_attribs, key) != Result_OK ) |
|
|
|
{ |
|
|
|
ret = Result_Error; |
|
|
|
break; |
|
|
@@ -234,7 +236,7 @@ Result_t ecb_encrypt( CryptoAttribs_t* attribs, const Key_t* const key ) |
|
|
|
} |
|
|
|
|
|
|
|
padded_attribs.padding = kPadding_None; |
|
|
|
res = crypt(&padded_attribs, key); |
|
|
|
res = aes_whole_blocks(&padded_attribs, key); |
|
|
|
if(NULL==attribs->output) |
|
|
|
{ |
|
|
|
attribs->output = (uint8_t*)malloc(padded_attribs.output_len); |
|
|
@@ -247,7 +249,7 @@ Result_t ecb_encrypt( CryptoAttribs_t* attribs, const Key_t* const key ) |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
res = crypt(attribs, key); |
|
|
|
res = aes_whole_blocks(attribs, key); |
|
|
|
} |
|
|
|
return res; |
|
|
|
} |
|
|
@@ -257,7 +259,7 @@ Result_t ecb_decrypt( CryptoAttribs_t* attribs, const Key_t* const key ) |
|
|
|
Result_t res = Result_OK; |
|
|
|
attribs->operation = kDecrypt; |
|
|
|
|
|
|
|
res = crypt(attribs, key); |
|
|
|
res = aes_whole_blocks(attribs, key); |
|
|
|
if( kPadding_PKCS7==attribs->padding ) |
|
|
|
{ |
|
|
|
size_t output_len=0; |
|
|
|