Path: blob/main/contrib/bearssl/src/symcipher/aes_ct_ctrcbc.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#include "inner.h"2526/* see bearssl_block.h */27void28br_aes_ct_ctrcbc_init(br_aes_ct_ctrcbc_keys *ctx,29const void *key, size_t len)30{31ctx->vtable = &br_aes_ct_ctrcbc_vtable;32ctx->num_rounds = br_aes_ct_keysched(ctx->skey, key, len);33}3435static void36xorbuf(void *dst, const void *src, size_t len)37{38unsigned char *d;39const unsigned char *s;4041d = dst;42s = src;43while (len -- > 0) {44*d ++ ^= *s ++;45}46}4748/* see bearssl_block.h */49void50br_aes_ct_ctrcbc_ctr(const br_aes_ct_ctrcbc_keys *ctx,51void *ctr, void *data, size_t len)52{53unsigned char *buf;54unsigned char *ivbuf;55uint32_t iv0, iv1, iv2, iv3;56uint32_t sk_exp[120];5758br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);5960/*61* We keep the counter as four 32-bit values, with big-endian62* convention, because that's what is expected for purposes of63* incrementing the counter value.64*/65ivbuf = ctr;66iv0 = br_dec32be(ivbuf + 0);67iv1 = br_dec32be(ivbuf + 4);68iv2 = br_dec32be(ivbuf + 8);69iv3 = br_dec32be(ivbuf + 12);7071buf = data;72while (len > 0) {73uint32_t q[8], carry;74unsigned char tmp[32];7576/*77* The bitslice implementation expects values in78* little-endian convention, so we have to byteswap them.79*/80q[0] = br_swap32(iv0);81q[2] = br_swap32(iv1);82q[4] = br_swap32(iv2);83q[6] = br_swap32(iv3);84iv3 ++;85carry = ~(iv3 | -iv3) >> 31;86iv2 += carry;87carry &= -(~(iv2 | -iv2) >> 31);88iv1 += carry;89carry &= -(~(iv1 | -iv1) >> 31);90iv0 += carry;91q[1] = br_swap32(iv0);92q[3] = br_swap32(iv1);93q[5] = br_swap32(iv2);94q[7] = br_swap32(iv3);95if (len > 16) {96iv3 ++;97carry = ~(iv3 | -iv3) >> 31;98iv2 += carry;99carry &= -(~(iv2 | -iv2) >> 31);100iv1 += carry;101carry &= -(~(iv1 | -iv1) >> 31);102iv0 += carry;103}104105br_aes_ct_ortho(q);106br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q);107br_aes_ct_ortho(q);108109br_enc32le(tmp, q[0]);110br_enc32le(tmp + 4, q[2]);111br_enc32le(tmp + 8, q[4]);112br_enc32le(tmp + 12, q[6]);113br_enc32le(tmp + 16, q[1]);114br_enc32le(tmp + 20, q[3]);115br_enc32le(tmp + 24, q[5]);116br_enc32le(tmp + 28, q[7]);117118if (len <= 32) {119xorbuf(buf, tmp, len);120break;121}122xorbuf(buf, tmp, 32);123buf += 32;124len -= 32;125}126br_enc32be(ivbuf + 0, iv0);127br_enc32be(ivbuf + 4, iv1);128br_enc32be(ivbuf + 8, iv2);129br_enc32be(ivbuf + 12, iv3);130}131132/* see bearssl_block.h */133void134br_aes_ct_ctrcbc_mac(const br_aes_ct_ctrcbc_keys *ctx,135void *cbcmac, const void *data, size_t len)136{137const unsigned char *buf;138uint32_t cm0, cm1, cm2, cm3;139uint32_t q[8];140uint32_t sk_exp[120];141142br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);143144buf = data;145cm0 = br_dec32le((unsigned char *)cbcmac + 0);146cm1 = br_dec32le((unsigned char *)cbcmac + 4);147cm2 = br_dec32le((unsigned char *)cbcmac + 8);148cm3 = br_dec32le((unsigned char *)cbcmac + 12);149q[1] = 0;150q[3] = 0;151q[5] = 0;152q[7] = 0;153154while (len > 0) {155q[0] = cm0 ^ br_dec32le(buf + 0);156q[2] = cm1 ^ br_dec32le(buf + 4);157q[4] = cm2 ^ br_dec32le(buf + 8);158q[6] = cm3 ^ br_dec32le(buf + 12);159160br_aes_ct_ortho(q);161br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q);162br_aes_ct_ortho(q);163164cm0 = q[0];165cm1 = q[2];166cm2 = q[4];167cm3 = q[6];168buf += 16;169len -= 16;170}171172br_enc32le((unsigned char *)cbcmac + 0, cm0);173br_enc32le((unsigned char *)cbcmac + 4, cm1);174br_enc32le((unsigned char *)cbcmac + 8, cm2);175br_enc32le((unsigned char *)cbcmac + 12, cm3);176}177178/* see bearssl_block.h */179void180br_aes_ct_ctrcbc_encrypt(const br_aes_ct_ctrcbc_keys *ctx,181void *ctr, void *cbcmac, void *data, size_t len)182{183/*184* When encrypting, the CBC-MAC processing must be lagging by185* one block, since it operates on the encrypted values, so186* it must wait for that encryption to complete.187*/188189unsigned char *buf;190unsigned char *ivbuf;191uint32_t iv0, iv1, iv2, iv3;192uint32_t cm0, cm1, cm2, cm3;193uint32_t sk_exp[120];194int first_iter;195196br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);197198/*199* We keep the counter as four 32-bit values, with big-endian200* convention, because that's what is expected for purposes of201* incrementing the counter value.202*/203ivbuf = ctr;204iv0 = br_dec32be(ivbuf + 0);205iv1 = br_dec32be(ivbuf + 4);206iv2 = br_dec32be(ivbuf + 8);207iv3 = br_dec32be(ivbuf + 12);208209/*210* The current CBC-MAC value is kept in little-endian convention.211*/212cm0 = br_dec32le((unsigned char *)cbcmac + 0);213cm1 = br_dec32le((unsigned char *)cbcmac + 4);214cm2 = br_dec32le((unsigned char *)cbcmac + 8);215cm3 = br_dec32le((unsigned char *)cbcmac + 12);216217buf = data;218first_iter = 1;219while (len > 0) {220uint32_t q[8], carry;221222/*223* The bitslice implementation expects values in224* little-endian convention, so we have to byteswap them.225*/226q[0] = br_swap32(iv0);227q[2] = br_swap32(iv1);228q[4] = br_swap32(iv2);229q[6] = br_swap32(iv3);230iv3 ++;231carry = ~(iv3 | -iv3) >> 31;232iv2 += carry;233carry &= -(~(iv2 | -iv2) >> 31);234iv1 += carry;235carry &= -(~(iv1 | -iv1) >> 31);236iv0 += carry;237238/*239* The odd values are used for CBC-MAC.240*/241q[1] = cm0;242q[3] = cm1;243q[5] = cm2;244q[7] = cm3;245246br_aes_ct_ortho(q);247br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q);248br_aes_ct_ortho(q);249250/*251* We do the XOR with the plaintext in 32-bit registers,252* so that the value are available for CBC-MAC processing253* as well.254*/255q[0] ^= br_dec32le(buf + 0);256q[2] ^= br_dec32le(buf + 4);257q[4] ^= br_dec32le(buf + 8);258q[6] ^= br_dec32le(buf + 12);259br_enc32le(buf + 0, q[0]);260br_enc32le(buf + 4, q[2]);261br_enc32le(buf + 8, q[4]);262br_enc32le(buf + 12, q[6]);263264buf += 16;265len -= 16;266267/*268* We set the cm* values to the block to encrypt in the269* next iteration.270*/271if (first_iter) {272first_iter = 0;273cm0 ^= q[0];274cm1 ^= q[2];275cm2 ^= q[4];276cm3 ^= q[6];277} else {278cm0 = q[0] ^ q[1];279cm1 = q[2] ^ q[3];280cm2 = q[4] ^ q[5];281cm3 = q[6] ^ q[7];282}283284/*285* If this was the last iteration, then compute the286* extra block encryption to complete CBC-MAC.287*/288if (len == 0) {289q[0] = cm0;290q[2] = cm1;291q[4] = cm2;292q[6] = cm3;293br_aes_ct_ortho(q);294br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q);295br_aes_ct_ortho(q);296cm0 = q[0];297cm1 = q[2];298cm2 = q[4];299cm3 = q[6];300break;301}302}303304br_enc32be(ivbuf + 0, iv0);305br_enc32be(ivbuf + 4, iv1);306br_enc32be(ivbuf + 8, iv2);307br_enc32be(ivbuf + 12, iv3);308br_enc32le((unsigned char *)cbcmac + 0, cm0);309br_enc32le((unsigned char *)cbcmac + 4, cm1);310br_enc32le((unsigned char *)cbcmac + 8, cm2);311br_enc32le((unsigned char *)cbcmac + 12, cm3);312}313314/* see bearssl_block.h */315void316br_aes_ct_ctrcbc_decrypt(const br_aes_ct_ctrcbc_keys *ctx,317void *ctr, void *cbcmac, void *data, size_t len)318{319unsigned char *buf;320unsigned char *ivbuf;321uint32_t iv0, iv1, iv2, iv3;322uint32_t cm0, cm1, cm2, cm3;323uint32_t sk_exp[120];324325br_aes_ct_skey_expand(sk_exp, ctx->num_rounds, ctx->skey);326327/*328* We keep the counter as four 32-bit values, with big-endian329* convention, because that's what is expected for purposes of330* incrementing the counter value.331*/332ivbuf = ctr;333iv0 = br_dec32be(ivbuf + 0);334iv1 = br_dec32be(ivbuf + 4);335iv2 = br_dec32be(ivbuf + 8);336iv3 = br_dec32be(ivbuf + 12);337338/*339* The current CBC-MAC value is kept in little-endian convention.340*/341cm0 = br_dec32le((unsigned char *)cbcmac + 0);342cm1 = br_dec32le((unsigned char *)cbcmac + 4);343cm2 = br_dec32le((unsigned char *)cbcmac + 8);344cm3 = br_dec32le((unsigned char *)cbcmac + 12);345346buf = data;347while (len > 0) {348uint32_t q[8], carry;349unsigned char tmp[16];350351/*352* The bitslice implementation expects values in353* little-endian convention, so we have to byteswap them.354*/355q[0] = br_swap32(iv0);356q[2] = br_swap32(iv1);357q[4] = br_swap32(iv2);358q[6] = br_swap32(iv3);359iv3 ++;360carry = ~(iv3 | -iv3) >> 31;361iv2 += carry;362carry &= -(~(iv2 | -iv2) >> 31);363iv1 += carry;364carry &= -(~(iv1 | -iv1) >> 31);365iv0 += carry;366367/*368* The odd values are used for CBC-MAC.369*/370q[1] = cm0 ^ br_dec32le(buf + 0);371q[3] = cm1 ^ br_dec32le(buf + 4);372q[5] = cm2 ^ br_dec32le(buf + 8);373q[7] = cm3 ^ br_dec32le(buf + 12);374375br_aes_ct_ortho(q);376br_aes_ct_bitslice_encrypt(ctx->num_rounds, sk_exp, q);377br_aes_ct_ortho(q);378379br_enc32le(tmp + 0, q[0]);380br_enc32le(tmp + 4, q[2]);381br_enc32le(tmp + 8, q[4]);382br_enc32le(tmp + 12, q[6]);383xorbuf(buf, tmp, 16);384cm0 = q[1];385cm1 = q[3];386cm2 = q[5];387cm3 = q[7];388buf += 16;389len -= 16;390}391392br_enc32be(ivbuf + 0, iv0);393br_enc32be(ivbuf + 4, iv1);394br_enc32be(ivbuf + 8, iv2);395br_enc32be(ivbuf + 12, iv3);396br_enc32le((unsigned char *)cbcmac + 0, cm0);397br_enc32le((unsigned char *)cbcmac + 4, cm1);398br_enc32le((unsigned char *)cbcmac + 8, cm2);399br_enc32le((unsigned char *)cbcmac + 12, cm3);400}401402/* see bearssl_block.h */403const br_block_ctrcbc_class br_aes_ct_ctrcbc_vtable = {404sizeof(br_aes_ct_ctrcbc_keys),40516,4064,407(void (*)(const br_block_ctrcbc_class **, const void *, size_t))408&br_aes_ct_ctrcbc_init,409(void (*)(const br_block_ctrcbc_class *const *,410void *, void *, void *, size_t))411&br_aes_ct_ctrcbc_encrypt,412(void (*)(const br_block_ctrcbc_class *const *,413void *, void *, void *, size_t))414&br_aes_ct_ctrcbc_decrypt,415(void (*)(const br_block_ctrcbc_class *const *,416void *, void *, size_t))417&br_aes_ct_ctrcbc_ctr,418(void (*)(const br_block_ctrcbc_class *const *,419void *, const void *, size_t))420&br_aes_ct_ctrcbc_mac421};422423424