LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-22-2014, 08:26 AM   #1
abirt
LQ Newbie
 
Registered: Apr 2014
Posts: 15

Rep: Reputation: Disabled
AES_CBC output difference between OpenSSL and Kernel crypto API


Hi all,

I made the same encryption code with OpenSSL API and kernel crypto API to test AES_CBC encryption for 3 different keys: 128, 192 and 256 bit long. I am using the same input and IV (initialization vector) for the three tests.
Here is the code used for AES_CBC encryption module with kernel crypto API:
Code:
int init_module(void)
{
int keylen[3]={16, 24, 32}, ret = 0, innents = 0, outnents = 0, inlen = 100, outlen = 112, j = 0;
uint8_t in[112], out[112], *key, iv[16]; 
struct crypto_ablkcipher *tfm;
struct scatterlist *insg, *outsg;
struct ablkcipher_request *req;
struct async_crypto_result tresult;

	printk(KERN_INFO "\n....Scatterlist crypto API: aes(cbc) start....\n");

	memset(in, 0x01, inlen);
	memset(in+inlen, (outlen-inlen), (outlen-inlen));
	innents = sg_init(outlen, in, &insg);
	printk("\n..Input+padding: %d: ", outlen);
	khexdump(outlen, in);

	memset(out, 0, outlen);
	outnents = sg_init(outlen, out, &outsg);
	printk("\n..Output: %d: ", outlen);
	khexdump(outlen, out);

	memset(iv, 0x0a, 16);
	printk("\n..IV: 16: ");
	khexdump(16, iv);

	tfm = crypto_alloc_ablkcipher("cbc(aes)", 0, 0);
	if (IS_ERR(tfm)) {
		printk(KERN_WARNING "\n..error::failed to load aes(cbc) transform\n");
		return 0;
	}

	init_completion(&tresult.completion);

	if ( !(req = ablkcipher_request_alloc(tfm, GFP_KERNEL)) ) { 
		printk(KERN_WARNING "\n..error::failed to allocate request\n");
		goto ret_0;
	}

	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, async_crypto_complete, &tresult); 
	crypto_ablkcipher_clear_flags(tfm, ~0);

	for (j = 0; j < 3; j++) {
		key = kmalloc(keylen[j] * sizeof(uint8_t), GFP_KERNEL);
		if (IS_ERR(key)) {
			printk(KERN_WARNING "\n..error::key allocation failure\n");
			goto ret_1;
		}
		memset(key, 0x0b, keylen[j]);	
		printk("\n..Key: %d: ", keylen[j]);
		khexdump(keylen[j], key);
		
		if ((ret = crypto_ablkcipher_setkey(tfm, key, keylen[j]))) { 
			printk(KERN_WARNING "\n..error::failed to set key\n");
			kfree(key);
			goto ret_1; 
		}
		ablkcipher_request_set_crypt(req, insg, outsg, outlen, iv);
		ret = crypto_ablkcipher_encrypt(req);
		if (ret == -EINPROGRESS || ret == -EBUSY) {
			ret = wait_for_completion_interruptible(&tresult.completion);
			if (!ret)
				ret = tresult.err;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))			
			INIT_COMPLETION(tresult.completion);
#else
			reinit_completion(&(tresult.completion));
#endif
		}
		if (ret) {
			printk(KERN_WARNING "\n..error::crypto_ablkcipher_digest returns: %d\n", ret);
			kfree(key);
			goto ret_1;
		}
		sg_copy_to_buffer(outsg, outnents, out, outlen);
		printk("\n..Output: %d:  ", outlen);
		khexdump(outlen, out);
		kfree(key);
	}	
ret_1:	
	ablkcipher_request_free(req);
ret_0:
	sg_free(insg, innents);
	sg_free(outsg, outnents);
	crypto_free_ablkcipher(tfm);
return 0;
}
And here is the code used for OpenSSL:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/hmac.h> 
#include <openssl/sha.h>
#include <openssl/md5.h>
#include <sys/time.h>

typedef const EVP_CIPHER* (*encrfun)(void);

void hexdump(int len, uint8_t *val) 
{
int i = 0;
	for (i = 0; i < len; i++)
		printf("%02x ", val[i]);	
	printf("\n");
}

int main(int argv, char **argc)
{
int keylen[3] = {16, 24, 32}, inlen = 100, bs = 0, outlen = 112, i = 0;
uint8_t in[100], out[112], *key = NULL, iv[16] = {0};
EVP_CIPHER_CTX *x = NULL;
encrfun encralg[3] = {EVP_aes_128_cbc, EVP_aes_192_cbc, EVP_aes_256_cbc};

	memset(in, 1, inlen);	
	printf("\nIn: %d: ", inlen);
	hexdump(inlen, in);
	
	memset(out, 0, outlen);

	memset(iv, 0x0a, 16);	
	printf("\nIV: 16: ");
	hexdump(16, iv);

	x = malloc(sizeof(EVP_CIPHER_CTX));
	if (!x) {
		printf("\nerror::EVP_CIPHER_CTX allocation failure\n");
		return 0;
	}

	for (i = 0; i < 3; i++) {
		key = malloc(keylen[i] * sizeof(uint8_t));
		if (!key) {
			printf("error::key allocation failure\n");
			free(x);
			return 0;
		}
		memset(key, 0x0b, keylen[i]);
		printf("\nKey: %d: ", keylen[i]);
		hexdump(keylen[i], key);

		EVP_CIPHER_CTX_init(x);
		if (!EVP_EncryptInit(x, encralg[i](), NULL, NULL)) {
			printf("error::EVP_EncryptInit()\n");
			free(key);
			EVP_CIPHER_CTX_cleanup(x);
			free(x);
			return 0;
		}

		EVP_CIPHER_CTX_set_key_length(x, keylen[i]);
		if (!EVP_EncryptInit(x, NULL, key, iv)) {
			printf("error::EVP_EncryptInit()\n");
			free(key);
			EVP_CIPHER_CTX_cleanup(x);
			free(x);	
			return 0;
		}

		bs = EVP_CIPHER_CTX_block_size(x);
		if (!EVP_EncryptUpdate(x, out, &bs, in, inlen)) {
			printf("error::EVP_EncryptUpdate()\n");
			free(key);
			EVP_CIPHER_CTX_cleanup(x);
			free(x);
			return 0;
		}
		outlen = 0;
		outlen += bs;
		if (!EVP_EncryptFinal(x, out+bs, &bs)) {
			printf("error::EVP_EncryptUpdate()\n");
			free(key);
			EVP_CIPHER_CTX_cleanup(x);
			free(x);
			return 0;
		}
		outlen += bs;
		printf("\nOut: %d: ", outlen);
		hexdump(outlen, out);
		memset(out, 0, outlen);

		EVP_CIPHER_CTX_cleanup(x);
		free(key);
	}
	free(x);
return 0;
}
My problem is that I am getting the same result between OpenSSL and kernel crypto only for AES_CBC_128. However, the results for AES_CBC_192 and AES_CBC_256 are different even if I am using the same IV, input and keys.
Here is the result of OpenSSL:
Code:
In: 100: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 

IV: 16: 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 

Key: 16: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
Out: 112: a5 59 0b 5f 0d 7d a9 fb 1d 1d a3 d0 95 87 0f 01 3e ad 82 55 3e 59 35 78 70 5d 49 5f 4e da e3 77 48 ac 5e 41 ab 5a 7f 1e 14 e6 b9 02 17 f1 11 55 ff 4f bc 32 3e 72 9d 0e d1 ba 9f f4 87 83 fb ee 91 61 ff 15 81 3d b6 7a e5 ff a4 71 a8 6f 38 79 39 1c 2f a0 6d ff 85 64 02 39 9c f7 e3 7e a5 f9 ce 3d 16 ea 65 cf 91 0b 50 db f6 73 52 de be 1c 

Key: 24: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
Out: 112: 77 12 21 56 62 fb ab 5b 0e 70 d8 5e 33 2e 1b 37 b1 92 bc b9 b5 0f d9 c4 49 b4 51 d3 3a dd f8 fc 6c 02 0a c9 08 89 b6 8b 57 ed 07 6e 4d 35 98 76 4a b7 f3 cc 35 2a 9b c4 59 37 18 cd a4 a8 3e f7 76 70 f4 6f ca 02 9f 6b 65 d8 0b 86 b5 48 16 92 c0 b6 8a 2d b5 3f fc 87 4f a5 8f 23 51 16 76 3c cf 5c 4f 14 e0 70 41 6d 7e 1a d6 a2 0c 2a ee cb 

Key: 32: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
Out: 112: d3 80 2e c9 73 e6 93 5a a3 2d 7b 88 f5 6a 21 19 fe 8b ff 7a 6e 18 e2 6e 0c 12 33 da 58 53 87 10 70 73 b3 29 eb fa 6a 69 85 00 3c 05 6f de 2b 8f 19 85 ed e2 28 5b 72 e9 7e 67 2d d5 e9 b4 c3 b3 74 c7 9b 8c ce 85 bd a2 d1 d4 87 ec 1e cf 18 30 63 05 3e 12 ea 32 87 8a 63 20 8a 66 e3 34 24 63 31 65 f9 16 bd e7 b8 de 41 ca 2e 47 46 62 aa ab
And here is the result of kernel crypto:
Code:
[23260.400939] ..Input+padding: 112: 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 

[23260.401049] ..IV: 16: 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 

[23260.401069] ..Key: 16: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
[23260.401085] ..Output: 112:  a5 59 0b 5f 0d 7d a9 fb 1d 1d a3 d0 95 87 0f 01 3e ad 82 55 3e 59 35 78 70 5d 49 5f 4e da e3 77 48 ac 5e 41 ab 5a 7f 1e 14 e6 b9 02 17 f1 11 55 ff 4f bc 32 3e 72 9d 0e d1 ba 9f f4 87 83 fb ee 91 61 ff 15 81 3d b6 7a e5 ff a4 71 a8 6f 38 79 39 1c 2f a0 6d ff 85 64 02 39 9c f7 e3 7e a5 f9 ce 3d 16 ea 65 cf 91 0b 50 db f6 73 52 de be 1c 

[23260.401140] ..Key: 24: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
[23260.401155] ..Output: 112:  a1 4b 6f 74 ff c9 29 30 d1 a2 48 03 e1 6b 7b e3 78 4d 7d 12 fa 7f 8e 79 2e c3 0b f5 c3 09 ae 38 e4 1c 62 b9 e1 cf 71 da 67 8b 91 40 af e5 8e 17 03 38 d9 1b ff 67 5a a8 20 d2 c6 27 f7 17 4f 90 70 9a 50 45 ec 3c 29 c9 21 65 29 92 70 a4 31 e6 7d 00 08 e1 38 c1 9a 04 12 37 bf 6d 00 a8 62 84 4f 72 52 30 4e f8 89 d8 01 4b da fb a7 06 28 ef 

[23260.401211] ..Key: 32: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 
[23260.401229] ..Output: 112:  0c bf 3e 4e a8 2e a0 a8 9c 08 b4 a0 d7 38 2d bc 6d 4f 7b 61 b7 56 5e ad 1f 06 aa b0 0a 71 58 2b 1d de 06 86 60 43 e6 c5 8e a7 6d 68 8e ea 57 99 8e e1 e6 32 58 f4 15 ff d9 2b 0c 88 e3 8d 97 44 59 f4 40 99 5b 1a af 77 94 dc 9e 41 9a 2c 6c 24 71 43 29 04 7a 5b 47 e7 89 bf 50 3f d6 85 d5 8e e9 a6 bd 2c a3 80 ff 6d a4 55 1a 1b be 7b 48 50
Could you help me to find the origin of the problem, Thanks in advance.

Best regards
 
Old 08-22-2014, 11:42 AM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
It looks like the kernel crypto API writes the MAC into your iv buffer, so you should reset it each time.
 
Old 08-25-2014, 02:22 AM   #3
abirt
LQ Newbie
 
Registered: Apr 2014
Posts: 15

Original Poster
Rep: Reputation: Disabled
Thanks ntubski, that was the solution to the problem.
best regards
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] unable to handle kernel paging request with scatterlist crypto API abirt Programming 4 04-28-2014 06:29 PM
LXer: Secure programming with the OpenSSL API, Part 1: Overview of the API LXer Syndicated Linux News 0 06-29-2012 12:30 PM
Help on linux kernel crypto API HSN Linux - Kernel 1 12-31-2010 02:29 PM
Install Crypto API on Linux Kernel saurabhchokshi Programming 4 04-30-2009 06:34 AM
How to use kernel's crypto API inside the kernel to compute an MD5 hash ? linuxabhinav Linux - Kernel 2 05-28-2008 11:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration