/*1* Copyright (c) 2016 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"2526static inline size_t27hash_size(const br_hash_class *dig)28{29return (unsigned)(dig->desc >> BR_HASHDESC_OUT_OFF)30& BR_HASHDESC_OUT_MASK;31}3233static inline size_t34block_size(const br_hash_class *dig)35{36unsigned ls;3738ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF)39& BR_HASHDESC_LBLEN_MASK;40return (size_t)1 << ls;41}4243/* see bearssl.h */44size_t45br_hmac_outCT(const br_hmac_context *ctx,46const void *data, size_t len, size_t min_len, size_t max_len,47void *out)48{49/*50* Method implemented here is inspired from the descriptions on:51* https://www.imperialviolet.org/2013/02/04/luckythirteen.html52*53* Principle: we input bytes one by one. We use a MUX to push54* padding bytes instead of data bytes when appropriate. At each55* block limit, we get the current hash function state: this is56* a potential output, since we handle MD padding ourselves.57*58* be 1 for big-endian, 0 for little-endian59* po minimal MD padding length60* bs block size (always a power of 2)61* hlen hash output size62*/6364const br_hash_class *dig;65br_hash_compat_context hc;66int be;67uint32_t po, bs;68uint32_t kr, km, kl, kz, u;69uint64_t count, ncount, bit_len;70unsigned char tmp1[64], tmp2[64];71size_t hlen;7273/*74* Copy the current hash context.75*/76hc = ctx->dig;7778/*79* Get function-specific information.80*/81dig = hc.vtable;82be = (dig->desc & BR_HASHDESC_MD_PADDING_BE) != 0;83po = 9;84if (dig->desc & BR_HASHDESC_MD_PADDING_128) {85po += 8;86}87bs = block_size(dig);88hlen = hash_size(dig);8990/*91* Get current input length and compute total bit length.92*/93count = dig->state(&hc.vtable, tmp1);94bit_len = (count + (uint64_t)len) << 3;9596/*97* We can input the blocks that we are sure we will use.98* This offers better performance (no MUX for these blocks)99* and also ensures that the remaining lengths fit on 32 bits.100*/101ncount = (count + (uint64_t)min_len) & ~(uint64_t)(bs - 1);102if (ncount > count) {103size_t zlen;104105zlen = (size_t)(ncount - count);106dig->update(&hc.vtable, data, zlen);107data = (const unsigned char *)data + zlen;108len -= zlen;109max_len -= zlen;110count = ncount;111}112113/*114* At that point:115* -- 'count' contains the number of bytes already processed116* (in total).117* -- We must input 'len' bytes. 'min_len' is unimportant: we118* used it to know how many full blocks we could process119* directly. Now only len and max_len matter.120*121* We compute kr, kl, kz and km.122* kr number of input bytes already in the current block123* km index of the first byte after the end of the last padding124* block, if length is max_len125* kz index of the last byte of the actual last padding block126* kl index of the start of the encoded length127*128* km, kz and kl are counted from the current offset in the129* input data.130*/131kr = (uint32_t)count & (bs - 1);132kz = ((kr + (uint32_t)len + po + bs - 1) & ~(bs - 1)) - 1 - kr;133kl = kz - 7;134km = ((kr + (uint32_t)max_len + po + bs - 1) & ~(bs - 1)) - kr;135136/*137* We must now process km bytes. For index u from 0 to km-1:138* d is from data[] if u < max_len, 0x00 otherwise139* e is an encoded length byte or 0x00, depending on u140* The tests for d and e need not be constant-time, since141* they relate only to u and max_len, not to the actual length.142*143* Actual input length is then:144* d if u < len145* 0x80 if u == len146* 0x00 if u > len and u < kl147* e if u >= kl148*149* Hash state is obtained whenever we reach a full block. This150* is the result we want if and only if u == kz.151*/152memset(tmp2, 0, sizeof tmp2);153for (u = 0; u < km; u ++) {154uint32_t v;155uint32_t d, e, x0, x1;156unsigned char x[1];157158d = (u < max_len) ? ((const unsigned char *)data)[u] : 0x00;159v = (kr + u) & (bs - 1);160if (v >= (bs - 8)) {161unsigned j;162163j = (v - (bs - 8)) << 3;164if (be) {165e = (uint32_t)(bit_len >> (56 - j));166} else {167e = (uint32_t)(bit_len >> j);168}169e &= 0xFF;170} else {171e = 0x00;172}173x0 = MUX(EQ(u, (uint32_t)len), 0x80, d);174x1 = MUX(LT(u, kl), 0x00, e);175x[0] = MUX(LE(u, (uint32_t)len), x0, x1);176dig->update(&hc.vtable, x, 1);177if (v == (bs - 1)) {178dig->state(&hc.vtable, tmp1);179CCOPY(EQ(u, kz), tmp2, tmp1, hlen);180}181}182183/*184* Inner hash output is in tmp2[]; we finish processing.185*/186dig->init(&hc.vtable);187dig->set_state(&hc.vtable, ctx->kso, (uint64_t)bs);188dig->update(&hc.vtable, tmp2, hlen);189dig->out(&hc.vtable, tmp2);190memcpy(out, tmp2, ctx->out_len);191return ctx->out_len;192}193194195