| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 | /* * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License").  You may not use * this file except in compliance with the License.  You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */#include <string.h>#include <openssl/crypto.h>#include <openssl/err.h>#include "crypto/modes.h"#ifndef OPENSSL_NO_OCB/* * Calculate the number of binary trailing zero's in any given number */static u32 ocb_ntz(u64 n){    u32 cnt = 0;    /*     * We do a right-to-left simple sequential search. This is surprisingly     * efficient as the distribution of trailing zeros is not uniform,     * e.g. the number of possible inputs with no trailing zeros is equal to     * the number with 1 or more; the number with exactly 1 is equal to the     * number with 2 or more, etc. Checking the last two bits covers 75% of     * all numbers. Checking the last three covers 87.5%     */    while (!(n & 1)) {        n >>= 1;        cnt++;    }    return cnt;}/* * Shift a block of 16 bytes left by shift bits */static void ocb_block_lshift(const unsigned char *in, size_t shift,                             unsigned char *out){    int i;    unsigned char carry = 0, carry_next;    for (i = 15; i >= 0; i--) {        carry_next = in[i] >> (8 - shift);        out[i] = (in[i] << shift) | carry;        carry = carry_next;    }}/* * Perform a "double" operation as per OCB spec */static void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out){    unsigned char mask;    /*     * Calculate the mask based on the most significant bit. There are more     * efficient ways to do this - but this way is constant time     */    mask = in->c[0] & 0x80;    mask >>= 7;    mask = (0 - mask) & 0x87;    ocb_block_lshift(in->c, 1, out->c);    out->c[15] ^= mask;}/* * Perform an xor on in1 and in2 - each of len bytes. Store result in out */static void ocb_block_xor(const unsigned char *in1,                          const unsigned char *in2, size_t len,                          unsigned char *out){    size_t i;    for (i = 0; i < len; i++) {        out[i] = in1[i] ^ in2[i];    }}/* * Lookup L_index in our lookup table. If we haven't already got it we need to * calculate it */static OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx){    size_t l_index = ctx->l_index;    if (idx <= l_index) {        return ctx->l + idx;    }    /* We don't have it - so calculate it */    if (idx >= ctx->max_l_index) {        void *tmp_ptr;        /*         * Each additional entry allows to process almost double as         * much data, so that in linear world the table will need to         * be expanded with smaller and smaller increments. Originally         * it was doubling in size, which was a waste. Growing it         * linearly is not formally optimal, but is simpler to implement.         * We grow table by minimally required 4*n that would accommodate         * the index.         */        ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3;        tmp_ptr = OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));        if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */            return NULL;        ctx->l = tmp_ptr;    }    while (l_index < idx) {        ocb_double(ctx->l + l_index, ctx->l + l_index + 1);        l_index++;    }    ctx->l_index = l_index;    return ctx->l + idx;}/* * Create a new OCB128_CONTEXT */OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec,                                  block128_f encrypt, block128_f decrypt,                                  ocb128_f stream){    OCB128_CONTEXT *octx;    int ret;    if ((octx = OPENSSL_malloc(sizeof(*octx))) != NULL) {        ret = CRYPTO_ocb128_init(octx, keyenc, keydec, encrypt, decrypt,                                 stream);        if (ret)            return octx;        OPENSSL_free(octx);    }    return NULL;}/* * Initialise an existing OCB128_CONTEXT */int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec,                       block128_f encrypt, block128_f decrypt,                       ocb128_f stream){    memset(ctx, 0, sizeof(*ctx));    ctx->l_index = 0;    ctx->max_l_index = 5;    if ((ctx->l = OPENSSL_malloc(ctx->max_l_index * 16)) == NULL)        return 0;    /*     * We set both the encryption and decryption key schedules - decryption     * needs both. Don't really need decryption schedule if only doing     * encryption - but it simplifies things to take it anyway     */    ctx->encrypt = encrypt;    ctx->decrypt = decrypt;    ctx->stream = stream;    ctx->keyenc = keyenc;    ctx->keydec = keydec;    /* L_* = ENCIPHER(K, zeros(128)) */    ctx->encrypt(ctx->l_star.c, ctx->l_star.c, ctx->keyenc);    /* L_$ = double(L_*) */    ocb_double(&ctx->l_star, &ctx->l_dollar);    /* L_0 = double(L_$) */    ocb_double(&ctx->l_dollar, ctx->l);    /* L_{i} = double(L_{i-1}) */    ocb_double(ctx->l, ctx->l+1);    ocb_double(ctx->l+1, ctx->l+2);    ocb_double(ctx->l+2, ctx->l+3);    ocb_double(ctx->l+3, ctx->l+4);    ctx->l_index = 4;   /* enough to process up to 496 bytes */    return 1;}/* * Copy an OCB128_CONTEXT object */int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src,                           void *keyenc, void *keydec){    memcpy(dest, src, sizeof(OCB128_CONTEXT));    if (keyenc)        dest->keyenc = keyenc;    if (keydec)        dest->keydec = keydec;    if (src->l) {        if ((dest->l = OPENSSL_malloc(src->max_l_index * 16)) == NULL)            return 0;        memcpy(dest->l, src->l, (src->l_index + 1) * 16);    }    return 1;}/* * Set the IV to be used for this operation. Must be 1 - 15 bytes. */int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv,                        size_t len, size_t taglen){    unsigned char ktop[16], tmp[16], mask;    unsigned char stretch[24], nonce[16];    size_t bottom, shift;    /*     * Spec says IV is 120 bits or fewer - it allows non byte aligned lengths.     * We don't support this at this stage     */    if ((len > 15) || (len < 1) || (taglen > 16) || (taglen < 1)) {        return -1;    }    /* Reset nonce-dependent variables */    memset(&ctx->sess, 0, sizeof(ctx->sess));    /* Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N */    nonce[0] = ((taglen * 8) % 128) << 1;    memset(nonce + 1, 0, 15);    memcpy(nonce + 16 - len, iv, len);    nonce[15 - len] |= 1;    /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */    memcpy(tmp, nonce, 16);    tmp[15] &= 0xc0;    ctx->encrypt(tmp, ktop, ctx->keyenc);    /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */    memcpy(stretch, ktop, 16);    ocb_block_xor(ktop, ktop + 1, 8, stretch + 16);    /* bottom = str2num(Nonce[123..128]) */    bottom = nonce[15] & 0x3f;    /* Offset_0 = Stretch[1+bottom..128+bottom] */    shift = bottom % 8;    ocb_block_lshift(stretch + (bottom / 8), shift, ctx->sess.offset.c);    mask = 0xff;    mask <<= 8 - shift;    ctx->sess.offset.c[15] |=        (*(stretch + (bottom / 8) + 16) & mask) >> (8 - shift);    return 1;}/* * Provide any AAD. This can be called multiple times. Only the final time can * have a partial block */int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,                      size_t len){    u64 i, all_num_blocks;    size_t num_blocks, last_len;    OCB_BLOCK tmp;    /* Calculate the number of blocks of AAD provided now, and so far */    num_blocks = len / 16;    all_num_blocks = num_blocks + ctx->sess.blocks_hashed;    /* Loop through all full blocks of AAD */    for (i = ctx->sess.blocks_hashed + 1; i <= all_num_blocks; i++) {        OCB_BLOCK *lookup;        /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */        lookup = ocb_lookup_l(ctx, ocb_ntz(i));        if (lookup == NULL)            return 0;        ocb_block16_xor(&ctx->sess.offset_aad, lookup, &ctx->sess.offset_aad);        memcpy(tmp.c, aad, 16);        aad += 16;        /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */        ocb_block16_xor(&ctx->sess.offset_aad, &tmp, &tmp);        ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);        ocb_block16_xor(&tmp, &ctx->sess.sum, &ctx->sess.sum);    }    /*     * Check if we have any partial blocks left over. This is only valid in the     * last call to this function     */    last_len = len % 16;    if (last_len > 0) {        /* Offset_* = Offset_m xor L_* */        ocb_block16_xor(&ctx->sess.offset_aad, &ctx->l_star,                        &ctx->sess.offset_aad);        /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */        memset(tmp.c, 0, 16);        memcpy(tmp.c, aad, last_len);        tmp.c[last_len] = 0x80;        ocb_block16_xor(&ctx->sess.offset_aad, &tmp, &tmp);        /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */        ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);        ocb_block16_xor(&tmp, &ctx->sess.sum, &ctx->sess.sum);    }    ctx->sess.blocks_hashed = all_num_blocks;    return 1;}/* * Provide any data to be encrypted. This can be called multiple times. Only * the final time can have a partial block */int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,                          const unsigned char *in, unsigned char *out,                          size_t len){    u64 i, all_num_blocks;    size_t num_blocks, last_len;    /*     * Calculate the number of blocks of data to be encrypted provided now, and     * so far     */    num_blocks = len / 16;    all_num_blocks = num_blocks + ctx->sess.blocks_processed;    if (num_blocks && all_num_blocks == (size_t)all_num_blocks        && ctx->stream != NULL) {        size_t max_idx = 0, top = (size_t)all_num_blocks;        /*         * See how many L_{i} entries we need to process data at hand         * and pre-compute missing entries in the table [if any]...         */        while (top >>= 1)            max_idx++;        if (ocb_lookup_l(ctx, max_idx) == NULL)            return 0;        ctx->stream(in, out, num_blocks, ctx->keyenc,                    (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,                    (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);    } else {        /* Loop through all full blocks to be encrypted */        for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {            OCB_BLOCK *lookup;            OCB_BLOCK tmp;            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */            lookup = ocb_lookup_l(ctx, ocb_ntz(i));            if (lookup == NULL)                return 0;            ocb_block16_xor(&ctx->sess.offset, lookup, &ctx->sess.offset);            memcpy(tmp.c, in, 16);            in += 16;            /* Checksum_i = Checksum_{i-1} xor P_i */            ocb_block16_xor(&tmp, &ctx->sess.checksum, &ctx->sess.checksum);            /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);            ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);            memcpy(out, tmp.c, 16);            out += 16;        }    }    /*     * Check if we have any partial blocks left over. This is only valid in the     * last call to this function     */    last_len = len % 16;    if (last_len > 0) {        OCB_BLOCK pad;        /* Offset_* = Offset_m xor L_* */        ocb_block16_xor(&ctx->sess.offset, &ctx->l_star, &ctx->sess.offset);        /* Pad = ENCIPHER(K, Offset_*) */        ctx->encrypt(ctx->sess.offset.c, pad.c, ctx->keyenc);        /* C_* = P_* xor Pad[1..bitlen(P_*)] */        ocb_block_xor(in, pad.c, last_len, out);        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */        memset(pad.c, 0, 16);           /* borrow pad */        memcpy(pad.c, in, last_len);        pad.c[last_len] = 0x80;        ocb_block16_xor(&pad, &ctx->sess.checksum, &ctx->sess.checksum);    }    ctx->sess.blocks_processed = all_num_blocks;    return 1;}/* * Provide any data to be decrypted. This can be called multiple times. Only * the final time can have a partial block */int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,                          const unsigned char *in, unsigned char *out,                          size_t len){    u64 i, all_num_blocks;    size_t num_blocks, last_len;    /*     * Calculate the number of blocks of data to be decrypted provided now, and     * so far     */    num_blocks = len / 16;    all_num_blocks = num_blocks + ctx->sess.blocks_processed;    if (num_blocks && all_num_blocks == (size_t)all_num_blocks        && ctx->stream != NULL) {        size_t max_idx = 0, top = (size_t)all_num_blocks;        /*         * See how many L_{i} entries we need to process data at hand         * and pre-compute missing entries in the table [if any]...         */        while (top >>= 1)            max_idx++;        if (ocb_lookup_l(ctx, max_idx) == NULL)            return 0;        ctx->stream(in, out, num_blocks, ctx->keydec,                    (size_t)ctx->sess.blocks_processed + 1, ctx->sess.offset.c,                    (const unsigned char (*)[16])ctx->l, ctx->sess.checksum.c);    } else {        OCB_BLOCK tmp;        /* Loop through all full blocks to be decrypted */        for (i = ctx->sess.blocks_processed + 1; i <= all_num_blocks; i++) {            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */            OCB_BLOCK *lookup = ocb_lookup_l(ctx, ocb_ntz(i));            if (lookup == NULL)                return 0;            ocb_block16_xor(&ctx->sess.offset, lookup, &ctx->sess.offset);            memcpy(tmp.c, in, 16);            in += 16;            /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);            ctx->decrypt(tmp.c, tmp.c, ctx->keydec);            ocb_block16_xor(&ctx->sess.offset, &tmp, &tmp);            /* Checksum_i = Checksum_{i-1} xor P_i */            ocb_block16_xor(&tmp, &ctx->sess.checksum, &ctx->sess.checksum);            memcpy(out, tmp.c, 16);            out += 16;        }    }    /*     * Check if we have any partial blocks left over. This is only valid in the     * last call to this function     */    last_len = len % 16;    if (last_len > 0) {        OCB_BLOCK pad;        /* Offset_* = Offset_m xor L_* */        ocb_block16_xor(&ctx->sess.offset, &ctx->l_star, &ctx->sess.offset);        /* Pad = ENCIPHER(K, Offset_*) */        ctx->encrypt(ctx->sess.offset.c, pad.c, ctx->keyenc);        /* P_* = C_* xor Pad[1..bitlen(C_*)] */        ocb_block_xor(in, pad.c, last_len, out);        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */        memset(pad.c, 0, 16);           /* borrow pad */        memcpy(pad.c, out, last_len);        pad.c[last_len] = 0x80;        ocb_block16_xor(&pad, &ctx->sess.checksum, &ctx->sess.checksum);    }    ctx->sess.blocks_processed = all_num_blocks;    return 1;}static int ocb_finish(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len,                      int write){    OCB_BLOCK tmp;    if (len > 16 || len < 1) {        return -1;    }    /*     * Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)     */    ocb_block16_xor(&ctx->sess.checksum, &ctx->sess.offset, &tmp);    ocb_block16_xor(&ctx->l_dollar, &tmp, &tmp);    ctx->encrypt(tmp.c, tmp.c, ctx->keyenc);    ocb_block16_xor(&tmp, &ctx->sess.sum, &tmp);    if (write) {        memcpy(tag, &tmp, len);        return 1;    } else {        return CRYPTO_memcmp(&tmp, tag, len);    }}/* * Calculate the tag and verify it against the supplied tag */int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag,                         size_t len){    return ocb_finish(ctx, (unsigned char*)tag, len, 0);}/* * Retrieve the calculated tag */int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len){    return ocb_finish(ctx, tag, len, 1);}/* * Release all resources */void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx){    if (ctx) {        OPENSSL_clear_free(ctx->l, ctx->max_l_index * 16);        OPENSSL_cleanse(ctx, sizeof(*ctx));    }}#endif                          /* OPENSSL_NO_OCB */
 |