/*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/*27* Implementation Notes28* ====================29*30* Since CTR and GHASH implementations can handle only full blocks, a31* 16-byte buffer (buf[]) is maintained in the context:32*33* - When processing AAD, buf[] contains the 0-15 unprocessed bytes.34*35* - When doing CTR encryption / decryption, buf[] contains the AES output36* for the last partial block, to be used with the next few bytes of37* data, as well as the already encrypted bytes. For instance, if the38* processed data length so far is 21 bytes, then buf[0..4] contains39* the five last encrypted bytes, and buf[5..15] contains the next 1140* AES output bytes to be XORed with the next 11 bytes of input.41*42* The recorded AES output bytes are used to complete the block when43* the corresponding bytes are obtained. Note that buf[] always44* contains the _encrypted_ bytes, whether we apply encryption or45* decryption: these bytes are used as input to GHASH when the block46* is complete.47*48* In both cases, the low bits of the data length counters (count_aad,49* count_ctr) are used to work out the current situation.50*/5152/* see bearssl_aead.h */53void54br_gcm_init(br_gcm_context *ctx, const br_block_ctr_class **bctx, br_ghash gh)55{56unsigned char iv[12];5758ctx->vtable = &br_gcm_vtable;59ctx->bctx = bctx;60ctx->gh = gh;6162/*63* The GHASH key h[] is the raw encryption of the all-zero64* block. Since we only have a CTR implementation, we use it65* with an all-zero IV and a zero counter, to CTR-encrypt an66* all-zero block.67*/68memset(ctx->h, 0, sizeof ctx->h);69memset(iv, 0, sizeof iv);70(*bctx)->run(bctx, iv, 0, ctx->h, sizeof ctx->h);71}7273/* see bearssl_aead.h */74void75br_gcm_reset(br_gcm_context *ctx, const void *iv, size_t len)76{77/*78* If the provided nonce is 12 bytes, then this is the initial79* IV for CTR mode; it will be used with a counter that starts80* at 2 (value 1 is for encrypting the GHASH output into the tag).81*82* If the provided nonce has any other length, then it is hashed83* (with GHASH) into a 16-byte value that will be the IV for CTR84* (both 12-byte IV and 32-bit counter).85*/86if (len == 12) {87memcpy(ctx->j0_1, iv, 12);88ctx->j0_2 = 1;89} else {90unsigned char ty[16], tmp[16];9192memset(ty, 0, sizeof ty);93ctx->gh(ty, ctx->h, iv, len);94memset(tmp, 0, 8);95br_enc64be(tmp + 8, (uint64_t)len << 3);96ctx->gh(ty, ctx->h, tmp, 16);97memcpy(ctx->j0_1, ty, 12);98ctx->j0_2 = br_dec32be(ty + 12);99}100ctx->jc = ctx->j0_2 + 1;101memset(ctx->y, 0, sizeof ctx->y);102ctx->count_aad = 0;103ctx->count_ctr = 0;104}105106/* see bearssl_aead.h */107void108br_gcm_aad_inject(br_gcm_context *ctx, const void *data, size_t len)109{110size_t ptr, dlen;111112ptr = (size_t)ctx->count_aad & (size_t)15;113if (ptr != 0) {114/*115* If there is a partial block, then we first try to116* complete it.117*/118size_t clen;119120clen = 16 - ptr;121if (len < clen) {122memcpy(ctx->buf + ptr, data, len);123ctx->count_aad += (uint64_t)len;124return;125}126memcpy(ctx->buf + ptr, data, clen);127ctx->gh(ctx->y, ctx->h, ctx->buf, 16);128data = (const unsigned char *)data + clen;129len -= clen;130ctx->count_aad += (uint64_t)clen;131}132133/*134* Now AAD is aligned on a 16-byte block (with regards to GHASH).135* We process all complete blocks, and save the last partial136* block.137*/138dlen = len & ~(size_t)15;139ctx->gh(ctx->y, ctx->h, data, dlen);140memcpy(ctx->buf, (const unsigned char *)data + dlen, len - dlen);141ctx->count_aad += (uint64_t)len;142}143144/* see bearssl_aead.h */145void146br_gcm_flip(br_gcm_context *ctx)147{148/*149* We complete the GHASH computation if there is a partial block.150* The GHASH implementation automatically applies padding with151* zeros.152*/153size_t ptr;154155ptr = (size_t)ctx->count_aad & (size_t)15;156if (ptr != 0) {157ctx->gh(ctx->y, ctx->h, ctx->buf, ptr);158}159}160161/* see bearssl_aead.h */162void163br_gcm_run(br_gcm_context *ctx, int encrypt, void *data, size_t len)164{165unsigned char *buf;166size_t ptr, dlen;167168buf = data;169ptr = (size_t)ctx->count_ctr & (size_t)15;170if (ptr != 0) {171/*172* If we have a partial block, then we try to complete it.173*/174size_t u, clen;175176clen = 16 - ptr;177if (len < clen) {178clen = len;179}180for (u = 0; u < clen; u ++) {181unsigned x, y;182183x = buf[u];184y = x ^ ctx->buf[ptr + u];185ctx->buf[ptr + u] = encrypt ? y : x;186buf[u] = y;187}188ctx->count_ctr += (uint64_t)clen;189buf += clen;190len -= clen;191if (ptr + clen < 16) {192return;193}194ctx->gh(ctx->y, ctx->h, ctx->buf, 16);195}196197/*198* Process full blocks.199*/200dlen = len & ~(size_t)15;201if (!encrypt) {202ctx->gh(ctx->y, ctx->h, buf, dlen);203}204ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->jc, buf, dlen);205if (encrypt) {206ctx->gh(ctx->y, ctx->h, buf, dlen);207}208buf += dlen;209len -= dlen;210ctx->count_ctr += (uint64_t)dlen;211212if (len > 0) {213/*214* There is a partial block.215*/216size_t u;217218memset(ctx->buf, 0, sizeof ctx->buf);219ctx->jc = (*ctx->bctx)->run(ctx->bctx, ctx->j0_1,220ctx->jc, ctx->buf, 16);221for (u = 0; u < len; u ++) {222unsigned x, y;223224x = buf[u];225y = x ^ ctx->buf[u];226ctx->buf[u] = encrypt ? y : x;227buf[u] = y;228}229ctx->count_ctr += (uint64_t)len;230}231}232233/* see bearssl_aead.h */234void235br_gcm_get_tag(br_gcm_context *ctx, void *tag)236{237size_t ptr;238unsigned char tmp[16];239240ptr = (size_t)ctx->count_ctr & (size_t)15;241if (ptr > 0) {242/*243* There is a partial block: encrypted/decrypted data has244* been produced, but the encrypted bytes must still be245* processed by GHASH.246*/247ctx->gh(ctx->y, ctx->h, ctx->buf, ptr);248}249250/*251* Final block for GHASH: the AAD and plaintext lengths (in bits).252*/253br_enc64be(tmp, ctx->count_aad << 3);254br_enc64be(tmp + 8, ctx->count_ctr << 3);255ctx->gh(ctx->y, ctx->h, tmp, 16);256257/*258* Tag is the GHASH output XORed with the encryption of the259* nonce with the initial counter value.260*/261memcpy(tag, ctx->y, 16);262(*ctx->bctx)->run(ctx->bctx, ctx->j0_1, ctx->j0_2, tag, 16);263}264265/* see bearssl_aead.h */266void267br_gcm_get_tag_trunc(br_gcm_context *ctx, void *tag, size_t len)268{269unsigned char tmp[16];270271br_gcm_get_tag(ctx, tmp);272memcpy(tag, tmp, len);273}274275/* see bearssl_aead.h */276uint32_t277br_gcm_check_tag_trunc(br_gcm_context *ctx, const void *tag, size_t len)278{279unsigned char tmp[16];280size_t u;281int x;282283br_gcm_get_tag(ctx, tmp);284x = 0;285for (u = 0; u < len; u ++) {286x |= tmp[u] ^ ((const unsigned char *)tag)[u];287}288return EQ0(x);289}290291/* see bearssl_aead.h */292uint32_t293br_gcm_check_tag(br_gcm_context *ctx, const void *tag)294{295return br_gcm_check_tag_trunc(ctx, tag, 16);296}297298/* see bearssl_aead.h */299const br_aead_class br_gcm_vtable = {30016,301(void (*)(const br_aead_class **, const void *, size_t))302&br_gcm_reset,303(void (*)(const br_aead_class **, const void *, size_t))304&br_gcm_aad_inject,305(void (*)(const br_aead_class **))306&br_gcm_flip,307(void (*)(const br_aead_class **, int, void *, size_t))308&br_gcm_run,309(void (*)(const br_aead_class **, void *))310&br_gcm_get_tag,311(uint32_t (*)(const br_aead_class **, const void *))312&br_gcm_check_tag,313(void (*)(const br_aead_class **, void *, size_t))314&br_gcm_get_tag_trunc,315(uint32_t (*)(const br_aead_class **, const void *, size_t))316&br_gcm_check_tag_trunc317};318319320