1238384Sjkim/* crypto/cmac/cmac.c */
2280304Sjkim/*
3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4238384Sjkim * project.
5238384Sjkim */
6238384Sjkim/* ====================================================================
7238384Sjkim * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
8238384Sjkim *
9238384Sjkim * Redistribution and use in source and binary forms, with or without
10238384Sjkim * modification, are permitted provided that the following conditions
11238384Sjkim * are met:
12238384Sjkim *
13238384Sjkim * 1. Redistributions of source code must retain the above copyright
14280304Sjkim *    notice, this list of conditions and the following disclaimer.
15238384Sjkim *
16238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright
17238384Sjkim *    notice, this list of conditions and the following disclaimer in
18238384Sjkim *    the documentation and/or other materials provided with the
19238384Sjkim *    distribution.
20238384Sjkim *
21238384Sjkim * 3. All advertising materials mentioning features or use of this
22238384Sjkim *    software must display the following acknowledgment:
23238384Sjkim *    "This product includes software developed by the OpenSSL Project
24238384Sjkim *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25238384Sjkim *
26238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27238384Sjkim *    endorse or promote products derived from this software without
28238384Sjkim *    prior written permission. For written permission, please contact
29238384Sjkim *    licensing@OpenSSL.org.
30238384Sjkim *
31238384Sjkim * 5. Products derived from this software may not be called "OpenSSL"
32238384Sjkim *    nor may "OpenSSL" appear in their names without prior written
33238384Sjkim *    permission of the OpenSSL Project.
34238384Sjkim *
35238384Sjkim * 6. Redistributions of any form whatsoever must retain the following
36238384Sjkim *    acknowledgment:
37238384Sjkim *    "This product includes software developed by the OpenSSL Project
38238384Sjkim *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39238384Sjkim *
40238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43238384Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
52238384Sjkim * ====================================================================
53238384Sjkim */
54238384Sjkim
55238384Sjkim#include <stdio.h>
56238384Sjkim#include <stdlib.h>
57238384Sjkim#include <string.h>
58238384Sjkim#include "cryptlib.h"
59238384Sjkim#include <openssl/cmac.h>
60238384Sjkim
61238384Sjkim#ifdef OPENSSL_FIPS
62280304Sjkim# include <openssl/fips.h>
63238384Sjkim#endif
64238384Sjkim
65280304Sjkimstruct CMAC_CTX_st {
66280304Sjkim    /* Cipher context to use */
67280304Sjkim    EVP_CIPHER_CTX cctx;
68280304Sjkim    /* Keys k1 and k2 */
69280304Sjkim    unsigned char k1[EVP_MAX_BLOCK_LENGTH];
70280304Sjkim    unsigned char k2[EVP_MAX_BLOCK_LENGTH];
71280304Sjkim    /* Temporary block */
72280304Sjkim    unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
73280304Sjkim    /* Last (possibly partial) block */
74280304Sjkim    unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
75280304Sjkim    /* Number of bytes in last block: -1 means context not initialised */
76280304Sjkim    int nlast_block;
77280304Sjkim};
78238384Sjkim
79238384Sjkim/* Make temporary keys K1 and K2 */
80238384Sjkim
81238384Sjkimstatic void make_kn(unsigned char *k1, unsigned char *l, int bl)
82280304Sjkim{
83280304Sjkim    int i;
84280304Sjkim    /* Shift block to left, including carry */
85280304Sjkim    for (i = 0; i < bl; i++) {
86280304Sjkim        k1[i] = l[i] << 1;
87280304Sjkim        if (i < bl - 1 && l[i + 1] & 0x80)
88280304Sjkim            k1[i] |= 1;
89280304Sjkim    }
90280304Sjkim    /* If MSB set fixup with R */
91280304Sjkim    if (l[0] & 0x80)
92280304Sjkim        k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
93280304Sjkim}
94238384Sjkim
95238384SjkimCMAC_CTX *CMAC_CTX_new(void)
96280304Sjkim{
97280304Sjkim    CMAC_CTX *ctx;
98280304Sjkim    ctx = OPENSSL_malloc(sizeof(CMAC_CTX));
99280304Sjkim    if (!ctx)
100280304Sjkim        return NULL;
101280304Sjkim    EVP_CIPHER_CTX_init(&ctx->cctx);
102280304Sjkim    ctx->nlast_block = -1;
103280304Sjkim    return ctx;
104280304Sjkim}
105238384Sjkim
106238384Sjkimvoid CMAC_CTX_cleanup(CMAC_CTX *ctx)
107280304Sjkim{
108238384Sjkim#ifdef OPENSSL_FIPS
109280304Sjkim    if (FIPS_mode() && !ctx->cctx.engine) {
110280304Sjkim        FIPS_cmac_ctx_cleanup(ctx);
111280304Sjkim        return;
112280304Sjkim    }
113238384Sjkim#endif
114280304Sjkim    EVP_CIPHER_CTX_cleanup(&ctx->cctx);
115280304Sjkim    OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
116280304Sjkim    OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
117280304Sjkim    OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
118280304Sjkim    OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
119280304Sjkim    ctx->nlast_block = -1;
120280304Sjkim}
121238384Sjkim
122238384SjkimEVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
123280304Sjkim{
124280304Sjkim    return &ctx->cctx;
125280304Sjkim}
126238384Sjkim
127238384Sjkimvoid CMAC_CTX_free(CMAC_CTX *ctx)
128280304Sjkim{
129284285Sjkim    if (!ctx)
130284285Sjkim        return;
131280304Sjkim    CMAC_CTX_cleanup(ctx);
132280304Sjkim    OPENSSL_free(ctx);
133280304Sjkim}
134238384Sjkim
135238384Sjkimint CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
136280304Sjkim{
137280304Sjkim    int bl;
138280304Sjkim    if (in->nlast_block == -1)
139280304Sjkim        return 0;
140280304Sjkim    if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
141280304Sjkim        return 0;
142280304Sjkim    bl = EVP_CIPHER_CTX_block_size(&in->cctx);
143280304Sjkim    memcpy(out->k1, in->k1, bl);
144280304Sjkim    memcpy(out->k2, in->k2, bl);
145280304Sjkim    memcpy(out->tbl, in->tbl, bl);
146280304Sjkim    memcpy(out->last_block, in->last_block, bl);
147280304Sjkim    out->nlast_block = in->nlast_block;
148280304Sjkim    return 1;
149280304Sjkim}
150238384Sjkim
151280304Sjkimint CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
152280304Sjkim              const EVP_CIPHER *cipher, ENGINE *impl)
153280304Sjkim{
154280304Sjkim    static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];
155238384Sjkim#ifdef OPENSSL_FIPS
156280304Sjkim    if (FIPS_mode()) {
157280304Sjkim        /* If we have an ENGINE need to allow non FIPS */
158280304Sjkim        if ((impl || ctx->cctx.engine)
159280304Sjkim            && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) {
160280304Sjkim            EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS);
161280304Sjkim            return 0;
162280304Sjkim        }
163280304Sjkim        /*
164280304Sjkim         * Other algorithm blocking will be done in FIPS_cmac_init, via
165280304Sjkim         * FIPS_cipherinit().
166280304Sjkim         */
167280304Sjkim        if (!impl && !ctx->cctx.engine)
168280304Sjkim            return FIPS_cmac_init(ctx, key, keylen, cipher, NULL);
169280304Sjkim    }
170238384Sjkim#endif
171280304Sjkim    /* All zeros means restart */
172280304Sjkim    if (!key && !cipher && !impl && keylen == 0) {
173280304Sjkim        /* Not initialised */
174280304Sjkim        if (ctx->nlast_block == -1)
175280304Sjkim            return 0;
176280304Sjkim        if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
177280304Sjkim            return 0;
178280304Sjkim        memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
179280304Sjkim        ctx->nlast_block = 0;
180280304Sjkim        return 1;
181280304Sjkim    }
182280304Sjkim    /* Initialiase context */
183280304Sjkim    if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
184280304Sjkim        return 0;
185280304Sjkim    /* Non-NULL key means initialisation complete */
186280304Sjkim    if (key) {
187280304Sjkim        int bl;
188280304Sjkim        if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
189280304Sjkim            return 0;
190280304Sjkim        if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
191280304Sjkim            return 0;
192280304Sjkim        if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
193280304Sjkim            return 0;
194280304Sjkim        bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
195280304Sjkim        if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
196280304Sjkim            return 0;
197280304Sjkim        make_kn(ctx->k1, ctx->tbl, bl);
198280304Sjkim        make_kn(ctx->k2, ctx->k1, bl);
199280304Sjkim        OPENSSL_cleanse(ctx->tbl, bl);
200280304Sjkim        /* Reset context again ready for first data block */
201280304Sjkim        if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
202280304Sjkim            return 0;
203280304Sjkim        /* Zero tbl so resume works */
204280304Sjkim        memset(ctx->tbl, 0, bl);
205280304Sjkim        ctx->nlast_block = 0;
206280304Sjkim    }
207280304Sjkim    return 1;
208280304Sjkim}
209238384Sjkim
210238384Sjkimint CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
211280304Sjkim{
212280304Sjkim    const unsigned char *data = in;
213280304Sjkim    size_t bl;
214238384Sjkim#ifdef OPENSSL_FIPS
215280304Sjkim    if (FIPS_mode() && !ctx->cctx.engine)
216280304Sjkim        return FIPS_cmac_update(ctx, in, dlen);
217238384Sjkim#endif
218280304Sjkim    if (ctx->nlast_block == -1)
219280304Sjkim        return 0;
220280304Sjkim    if (dlen == 0)
221280304Sjkim        return 1;
222280304Sjkim    bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
223280304Sjkim    /* Copy into partial block if we need to */
224280304Sjkim    if (ctx->nlast_block > 0) {
225280304Sjkim        size_t nleft;
226280304Sjkim        nleft = bl - ctx->nlast_block;
227280304Sjkim        if (dlen < nleft)
228280304Sjkim            nleft = dlen;
229280304Sjkim        memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
230280304Sjkim        dlen -= nleft;
231280304Sjkim        ctx->nlast_block += nleft;
232280304Sjkim        /* If no more to process return */
233280304Sjkim        if (dlen == 0)
234280304Sjkim            return 1;
235280304Sjkim        data += nleft;
236280304Sjkim        /* Else not final block so encrypt it */
237280304Sjkim        if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
238280304Sjkim            return 0;
239280304Sjkim    }
240280304Sjkim    /* Encrypt all but one of the complete blocks left */
241280304Sjkim    while (dlen > bl) {
242280304Sjkim        if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
243280304Sjkim            return 0;
244280304Sjkim        dlen -= bl;
245280304Sjkim        data += bl;
246280304Sjkim    }
247280304Sjkim    /* Copy any data left to last block buffer */
248280304Sjkim    memcpy(ctx->last_block, data, dlen);
249280304Sjkim    ctx->nlast_block = dlen;
250280304Sjkim    return 1;
251238384Sjkim
252280304Sjkim}
253238384Sjkim
254238384Sjkimint CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
255280304Sjkim{
256280304Sjkim    int i, bl, lb;
257238384Sjkim#ifdef OPENSSL_FIPS
258280304Sjkim    if (FIPS_mode() && !ctx->cctx.engine)
259280304Sjkim        return FIPS_cmac_final(ctx, out, poutlen);
260238384Sjkim#endif
261280304Sjkim    if (ctx->nlast_block == -1)
262280304Sjkim        return 0;
263280304Sjkim    bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);
264280304Sjkim    *poutlen = (size_t)bl;
265280304Sjkim    if (!out)
266280304Sjkim        return 1;
267280304Sjkim    lb = ctx->nlast_block;
268280304Sjkim    /* Is last block complete? */
269280304Sjkim    if (lb == bl) {
270280304Sjkim        for (i = 0; i < bl; i++)
271280304Sjkim            out[i] = ctx->last_block[i] ^ ctx->k1[i];
272280304Sjkim    } else {
273280304Sjkim        ctx->last_block[lb] = 0x80;
274280304Sjkim        if (bl - lb > 1)
275280304Sjkim            memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
276280304Sjkim        for (i = 0; i < bl; i++)
277280304Sjkim            out[i] = ctx->last_block[i] ^ ctx->k2[i];
278280304Sjkim    }
279280304Sjkim    if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
280280304Sjkim        OPENSSL_cleanse(out, bl);
281280304Sjkim        return 0;
282280304Sjkim    }
283280304Sjkim    return 1;
284280304Sjkim}
285238384Sjkim
286238384Sjkimint CMAC_resume(CMAC_CTX *ctx)
287280304Sjkim{
288280304Sjkim    if (ctx->nlast_block == -1)
289280304Sjkim        return 0;
290280304Sjkim    /*
291280304Sjkim     * The buffer "tbl" containes the last fully encrypted block which is the
292280304Sjkim     * last IV (or all zeroes if no last encrypted block). The last block has
293280304Sjkim     * not been modified since CMAC_final(). So reinitliasing using the last
294280304Sjkim     * decrypted block will allow CMAC to continue after calling
295280304Sjkim     * CMAC_Final().
296280304Sjkim     */
297280304Sjkim    return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
298280304Sjkim}
299