1214501Srpaulo/* 2214501Srpaulo * AES-128 CBC 3214501Srpaulo * 4214501Srpaulo * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> 5214501Srpaulo * 6252726Srpaulo * This software may be distributed under the terms of the BSD license. 7252726Srpaulo * See README for more details. 8214501Srpaulo */ 9214501Srpaulo 10214501Srpaulo#include "includes.h" 11214501Srpaulo 12214501Srpaulo#include "common.h" 13214501Srpaulo#include "aes.h" 14214501Srpaulo#include "aes_wrap.h" 15214501Srpaulo 16214501Srpaulo/** 17214501Srpaulo * aes_128_cbc_encrypt - AES-128 CBC encryption 18214501Srpaulo * @key: Encryption key 19214501Srpaulo * @iv: Encryption IV for CBC mode (16 bytes) 20214501Srpaulo * @data: Data to encrypt in-place 21214501Srpaulo * @data_len: Length of data in bytes (must be divisible by 16) 22214501Srpaulo * Returns: 0 on success, -1 on failure 23214501Srpaulo */ 24214501Srpauloint aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 25214501Srpaulo{ 26214501Srpaulo void *ctx; 27214501Srpaulo u8 cbc[AES_BLOCK_SIZE]; 28214501Srpaulo u8 *pos = data; 29214501Srpaulo int i, j, blocks; 30214501Srpaulo 31214501Srpaulo ctx = aes_encrypt_init(key, 16); 32214501Srpaulo if (ctx == NULL) 33214501Srpaulo return -1; 34214501Srpaulo os_memcpy(cbc, iv, AES_BLOCK_SIZE); 35214501Srpaulo 36214501Srpaulo blocks = data_len / AES_BLOCK_SIZE; 37214501Srpaulo for (i = 0; i < blocks; i++) { 38214501Srpaulo for (j = 0; j < AES_BLOCK_SIZE; j++) 39214501Srpaulo cbc[j] ^= pos[j]; 40214501Srpaulo aes_encrypt(ctx, cbc, cbc); 41214501Srpaulo os_memcpy(pos, cbc, AES_BLOCK_SIZE); 42214501Srpaulo pos += AES_BLOCK_SIZE; 43214501Srpaulo } 44214501Srpaulo aes_encrypt_deinit(ctx); 45214501Srpaulo return 0; 46214501Srpaulo} 47214501Srpaulo 48214501Srpaulo 49214501Srpaulo/** 50214501Srpaulo * aes_128_cbc_decrypt - AES-128 CBC decryption 51214501Srpaulo * @key: Decryption key 52214501Srpaulo * @iv: Decryption IV for CBC mode (16 bytes) 53214501Srpaulo * @data: Data to decrypt in-place 54214501Srpaulo * @data_len: Length of data in bytes (must be divisible by 16) 55214501Srpaulo * Returns: 0 on success, -1 on failure 56214501Srpaulo */ 57214501Srpauloint aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 58214501Srpaulo{ 59214501Srpaulo void *ctx; 60214501Srpaulo u8 cbc[AES_BLOCK_SIZE], tmp[AES_BLOCK_SIZE]; 61214501Srpaulo u8 *pos = data; 62214501Srpaulo int i, j, blocks; 63214501Srpaulo 64214501Srpaulo ctx = aes_decrypt_init(key, 16); 65214501Srpaulo if (ctx == NULL) 66214501Srpaulo return -1; 67214501Srpaulo os_memcpy(cbc, iv, AES_BLOCK_SIZE); 68214501Srpaulo 69214501Srpaulo blocks = data_len / AES_BLOCK_SIZE; 70214501Srpaulo for (i = 0; i < blocks; i++) { 71214501Srpaulo os_memcpy(tmp, pos, AES_BLOCK_SIZE); 72214501Srpaulo aes_decrypt(ctx, pos, pos); 73214501Srpaulo for (j = 0; j < AES_BLOCK_SIZE; j++) 74214501Srpaulo pos[j] ^= cbc[j]; 75214501Srpaulo os_memcpy(cbc, tmp, AES_BLOCK_SIZE); 76214501Srpaulo pos += AES_BLOCK_SIZE; 77214501Srpaulo } 78214501Srpaulo aes_decrypt_deinit(ctx); 79214501Srpaulo return 0; 80214501Srpaulo} 81