Path: blob/main/contrib/bearssl/src/symcipher/aes_x86ni_cbcenc.c
39482 views
/*1* Copyright (c) 2017 Thomas Pornin <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining4* a copy of this software and associated documentation files (the5* "Software"), to deal in the Software without restriction, including6* without limitation the rights to use, copy, modify, merge, publish,7* distribute, sublicense, and/or sell copies of the Software, and to8* permit persons to whom the Software is furnished to do so, subject to9* the following conditions:10*11* The above copyright notice and this permission notice shall be12* included in all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS18* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN19* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN20* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*/2324#define BR_ENABLE_INTRINSICS 125#include "inner.h"2627#if BR_AES_X86NI2829/* see bearssl_block.h */30const br_block_cbcenc_class *31br_aes_x86ni_cbcenc_get_vtable(void)32{33return br_aes_x86ni_supported() ? &br_aes_x86ni_cbcenc_vtable : NULL;34}3536/* see bearssl_block.h */37void38br_aes_x86ni_cbcenc_init(br_aes_x86ni_cbcenc_keys *ctx,39const void *key, size_t len)40{41ctx->vtable = &br_aes_x86ni_cbcenc_vtable;42ctx->num_rounds = br_aes_x86ni_keysched_enc(ctx->skey.skni, key, len);43}4445BR_TARGETS_X86_UP4647/* see bearssl_block.h */48BR_TARGET("sse2,aes")49void50br_aes_x86ni_cbcenc_run(const br_aes_x86ni_cbcenc_keys *ctx,51void *iv, void *data, size_t len)52{53unsigned char *buf;54unsigned num_rounds;55__m128i sk[15], ivx;56unsigned u;5758buf = data;59ivx = _mm_loadu_si128(iv);60num_rounds = ctx->num_rounds;61for (u = 0; u <= num_rounds; u ++) {62sk[u] = _mm_loadu_si128((void *)(ctx->skey.skni + (u << 4)));63}64while (len > 0) {65__m128i x;6667x = _mm_xor_si128(_mm_loadu_si128((void *)buf), ivx);68x = _mm_xor_si128(x, sk[0]);69x = _mm_aesenc_si128(x, sk[1]);70x = _mm_aesenc_si128(x, sk[2]);71x = _mm_aesenc_si128(x, sk[3]);72x = _mm_aesenc_si128(x, sk[4]);73x = _mm_aesenc_si128(x, sk[5]);74x = _mm_aesenc_si128(x, sk[6]);75x = _mm_aesenc_si128(x, sk[7]);76x = _mm_aesenc_si128(x, sk[8]);77x = _mm_aesenc_si128(x, sk[9]);78if (num_rounds == 10) {79x = _mm_aesenclast_si128(x, sk[10]);80} else if (num_rounds == 12) {81x = _mm_aesenc_si128(x, sk[10]);82x = _mm_aesenc_si128(x, sk[11]);83x = _mm_aesenclast_si128(x, sk[12]);84} else {85x = _mm_aesenc_si128(x, sk[10]);86x = _mm_aesenc_si128(x, sk[11]);87x = _mm_aesenc_si128(x, sk[12]);88x = _mm_aesenc_si128(x, sk[13]);89x = _mm_aesenclast_si128(x, sk[14]);90}91ivx = x;92_mm_storeu_si128((void *)buf, x);93buf += 16;94len -= 16;95}96_mm_storeu_si128(iv, ivx);97}9899BR_TARGETS_X86_DOWN100101/* see bearssl_block.h */102const br_block_cbcenc_class br_aes_x86ni_cbcenc_vtable = {103sizeof(br_aes_x86ni_cbcenc_keys),10416,1054,106(void (*)(const br_block_cbcenc_class **, const void *, size_t))107&br_aes_x86ni_cbcenc_init,108(void (*)(const br_block_cbcenc_class *const *, void *, void *, size_t))109&br_aes_x86ni_cbcenc_run110};111112#else113114/* see bearssl_block.h */115const br_block_cbcenc_class *116br_aes_x86ni_cbcenc_get_vtable(void)117{118return NULL;119}120121#endif122123124