1214501Srpaulo/* 2214501Srpaulo * AES-128 CTR 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_ctr_encrypt - AES-128 CTR mode encryption 18214501Srpaulo * @key: Key for encryption (16 bytes) 19214501Srpaulo * @nonce: Nonce for counter mode (16 bytes) 20214501Srpaulo * @data: Data to encrypt in-place 21214501Srpaulo * @data_len: Length of data in bytes 22214501Srpaulo * Returns: 0 on success, -1 on failure 23214501Srpaulo */ 24214501Srpauloint aes_128_ctr_encrypt(const u8 *key, const u8 *nonce, 25214501Srpaulo u8 *data, size_t data_len) 26214501Srpaulo{ 27214501Srpaulo void *ctx; 28214501Srpaulo size_t j, len, left = data_len; 29214501Srpaulo int i; 30214501Srpaulo u8 *pos = data; 31214501Srpaulo u8 counter[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; 32214501Srpaulo 33214501Srpaulo ctx = aes_encrypt_init(key, 16); 34214501Srpaulo if (ctx == NULL) 35214501Srpaulo return -1; 36214501Srpaulo os_memcpy(counter, nonce, AES_BLOCK_SIZE); 37214501Srpaulo 38214501Srpaulo while (left > 0) { 39214501Srpaulo aes_encrypt(ctx, counter, buf); 40214501Srpaulo 41214501Srpaulo len = (left < AES_BLOCK_SIZE) ? left : AES_BLOCK_SIZE; 42214501Srpaulo for (j = 0; j < len; j++) 43214501Srpaulo pos[j] ^= buf[j]; 44214501Srpaulo pos += len; 45214501Srpaulo left -= len; 46214501Srpaulo 47214501Srpaulo for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) { 48214501Srpaulo counter[i]++; 49214501Srpaulo if (counter[i]) 50214501Srpaulo break; 51214501Srpaulo } 52214501Srpaulo } 53214501Srpaulo aes_encrypt_deinit(ctx); 54214501Srpaulo return 0; 55214501Srpaulo} 56