13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * AES-128 CBC
33ff40c12SJohn Marino  *
43ff40c12SJohn Marino  * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
53ff40c12SJohn Marino  *
63ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
73ff40c12SJohn Marino  * See README for more details.
83ff40c12SJohn Marino  */
93ff40c12SJohn Marino 
103ff40c12SJohn Marino #include "includes.h"
113ff40c12SJohn Marino 
123ff40c12SJohn Marino #include "common.h"
133ff40c12SJohn Marino #include "aes.h"
143ff40c12SJohn Marino #include "aes_wrap.h"
153ff40c12SJohn Marino 
163ff40c12SJohn Marino /**
173ff40c12SJohn Marino  * aes_128_cbc_encrypt - AES-128 CBC encryption
183ff40c12SJohn Marino  * @key: Encryption key
193ff40c12SJohn Marino  * @iv: Encryption IV for CBC mode (16 bytes)
203ff40c12SJohn Marino  * @data: Data to encrypt in-place
213ff40c12SJohn Marino  * @data_len: Length of data in bytes (must be divisible by 16)
223ff40c12SJohn Marino  * Returns: 0 on success, -1 on failure
233ff40c12SJohn Marino  */
aes_128_cbc_encrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)243ff40c12SJohn Marino int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
253ff40c12SJohn Marino {
263ff40c12SJohn Marino 	void *ctx;
273ff40c12SJohn Marino 	u8 cbc[AES_BLOCK_SIZE];
283ff40c12SJohn Marino 	u8 *pos = data;
293ff40c12SJohn Marino 	int i, j, blocks;
303ff40c12SJohn Marino 
31*a1157835SDaniel Fojt 	if (TEST_FAIL())
32*a1157835SDaniel Fojt 		return -1;
33*a1157835SDaniel Fojt 
343ff40c12SJohn Marino 	ctx = aes_encrypt_init(key, 16);
353ff40c12SJohn Marino 	if (ctx == NULL)
363ff40c12SJohn Marino 		return -1;
373ff40c12SJohn Marino 	os_memcpy(cbc, iv, AES_BLOCK_SIZE);
383ff40c12SJohn Marino 
393ff40c12SJohn Marino 	blocks = data_len / AES_BLOCK_SIZE;
403ff40c12SJohn Marino 	for (i = 0; i < blocks; i++) {
413ff40c12SJohn Marino 		for (j = 0; j < AES_BLOCK_SIZE; j++)
423ff40c12SJohn Marino 			cbc[j] ^= pos[j];
433ff40c12SJohn Marino 		aes_encrypt(ctx, cbc, cbc);
443ff40c12SJohn Marino 		os_memcpy(pos, cbc, AES_BLOCK_SIZE);
453ff40c12SJohn Marino 		pos += AES_BLOCK_SIZE;
463ff40c12SJohn Marino 	}
473ff40c12SJohn Marino 	aes_encrypt_deinit(ctx);
483ff40c12SJohn Marino 	return 0;
493ff40c12SJohn Marino }
503ff40c12SJohn Marino 
513ff40c12SJohn Marino 
523ff40c12SJohn Marino /**
533ff40c12SJohn Marino  * aes_128_cbc_decrypt - AES-128 CBC decryption
543ff40c12SJohn Marino  * @key: Decryption key
553ff40c12SJohn Marino  * @iv: Decryption IV for CBC mode (16 bytes)
563ff40c12SJohn Marino  * @data: Data to decrypt in-place
573ff40c12SJohn Marino  * @data_len: Length of data in bytes (must be divisible by 16)
583ff40c12SJohn Marino  * Returns: 0 on success, -1 on failure
593ff40c12SJohn Marino  */
aes_128_cbc_decrypt(const u8 * key,const u8 * iv,u8 * data,size_t data_len)603ff40c12SJohn Marino int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
613ff40c12SJohn Marino {
623ff40c12SJohn Marino 	void *ctx;
633ff40c12SJohn Marino 	u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE];
643ff40c12SJohn Marino 	u8 *pos = data;
653ff40c12SJohn Marino 	int i, j, blocks;
663ff40c12SJohn Marino 
67*a1157835SDaniel Fojt 	if (TEST_FAIL())
68*a1157835SDaniel Fojt 		return -1;
69*a1157835SDaniel Fojt 
703ff40c12SJohn Marino 	ctx = aes_decrypt_init(key, 16);
713ff40c12SJohn Marino 	if (ctx == NULL)
723ff40c12SJohn Marino 		return -1;
733ff40c12SJohn Marino 	os_memcpy(cbc, iv, AES_BLOCK_SIZE);
743ff40c12SJohn Marino 
753ff40c12SJohn Marino 	blocks = data_len / AES_BLOCK_SIZE;
763ff40c12SJohn Marino 	for (i = 0; i < blocks; i++) {
773ff40c12SJohn Marino 		os_memcpy(tmp, pos, AES_BLOCK_SIZE);
783ff40c12SJohn Marino 		aes_decrypt(ctx, pos, pos);
793ff40c12SJohn Marino 		for (j = 0; j < AES_BLOCK_SIZE; j++)
803ff40c12SJohn Marino 			pos[j] ^= cbc[j];
813ff40c12SJohn Marino 		os_memcpy(cbc, tmp, AES_BLOCK_SIZE);
823ff40c12SJohn Marino 		pos += AES_BLOCK_SIZE;
833ff40c12SJohn Marino 	}
843ff40c12SJohn Marino 	aes_decrypt_deinit(ctx);
853ff40c12SJohn Marino 	return 0;
863ff40c12SJohn Marino }
87