Remove /* foo.c */ comments
[openssl.git] / crypto / cmac / cmac.c
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2010 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  */
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include "internal/cryptlib.h"
58 #include <openssl/cmac.h>
59
60 struct CMAC_CTX_st {
61     /* Cipher context to use */
62     EVP_CIPHER_CTX *cctx;
63     /* Keys k1 and k2 */
64     unsigned char k1[EVP_MAX_BLOCK_LENGTH];
65     unsigned char k2[EVP_MAX_BLOCK_LENGTH];
66     /* Temporary block */
67     unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
68     /* Last (possibly partial) block */
69     unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
70     /* Number of bytes in last block: -1 means context not initialised */
71     int nlast_block;
72 };
73
74 /* Make temporary keys K1 and K2 */
75
76 static void make_kn(unsigned char *k1, const unsigned char *l, int bl)
77 {
78     int i;
79     unsigned char c = l[0], carry = c >> 7, cnext;
80
81     /* Shift block to left, including carry */
82     for (i = 0; i < bl - 1; i++, c = cnext)
83         k1[i] = (c << 1) | ((cnext = l[i + 1]) >> 7);
84
85     /* If MSB set fixup with R */
86     k1[i] = (c << 1) ^ ((0 - carry) & (bl == 16 ? 0x87 : 0x1b));
87 }
88
89 CMAC_CTX *CMAC_CTX_new(void)
90 {
91     CMAC_CTX *ctx;
92
93     ctx = OPENSSL_malloc(sizeof(*ctx));
94     if (ctx == NULL)
95         return NULL;
96     ctx->cctx = EVP_CIPHER_CTX_new();
97     if (ctx->cctx == NULL) {
98         OPENSSL_free(ctx);
99         return NULL;
100     }
101     ctx->nlast_block = -1;
102     return ctx;
103 }
104
105 void CMAC_CTX_cleanup(CMAC_CTX *ctx)
106 {
107     EVP_CIPHER_CTX_free(ctx->cctx);
108     OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
109     OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
110     OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
111     OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
112     ctx->nlast_block = -1;
113 }
114
115 EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
116 {
117     return ctx->cctx;
118 }
119
120 void CMAC_CTX_free(CMAC_CTX *ctx)
121 {
122     if (!ctx)
123         return;
124     CMAC_CTX_cleanup(ctx);
125     OPENSSL_free(ctx);
126 }
127
128 int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
129 {
130     int bl;
131     if (in->nlast_block == -1)
132         return 0;
133     if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
134         return 0;
135     bl = EVP_CIPHER_CTX_block_size(in->cctx);
136     memcpy(out->k1, in->k1, bl);
137     memcpy(out->k2, in->k2, bl);
138     memcpy(out->tbl, in->tbl, bl);
139     memcpy(out->last_block, in->last_block, bl);
140     out->nlast_block = in->nlast_block;
141     return 1;
142 }
143
144 int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
145               const EVP_CIPHER *cipher, ENGINE *impl)
146 {
147     static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
148     /* All zeros means restart */
149     if (!key && !cipher && !impl && keylen == 0) {
150         /* Not initialised */
151         if (ctx->nlast_block == -1)
152             return 0;
153         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
154             return 0;
155         memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(ctx->cctx));
156         ctx->nlast_block = 0;
157         return 1;
158     }
159     /* Initialiase context */
160     if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
161         return 0;
162     /* Non-NULL key means initialisation complete */
163     if (key) {
164         int bl;
165         if (!EVP_CIPHER_CTX_cipher(ctx->cctx))
166             return 0;
167         if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen))
168             return 0;
169         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv))
170             return 0;
171         bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
172         if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl))
173             return 0;
174         make_kn(ctx->k1, ctx->tbl, bl);
175         make_kn(ctx->k2, ctx->k1, bl);
176         OPENSSL_cleanse(ctx->tbl, bl);
177         /* Reset context again ready for first data block */
178         if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
179             return 0;
180         /* Zero tbl so resume works */
181         memset(ctx->tbl, 0, bl);
182         ctx->nlast_block = 0;
183     }
184     return 1;
185 }
186
187 int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
188 {
189     const unsigned char *data = in;
190     size_t bl;
191     if (ctx->nlast_block == -1)
192         return 0;
193     if (dlen == 0)
194         return 1;
195     bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
196     /* Copy into partial block if we need to */
197     if (ctx->nlast_block > 0) {
198         size_t nleft;
199         nleft = bl - ctx->nlast_block;
200         if (dlen < nleft)
201             nleft = dlen;
202         memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
203         dlen -= nleft;
204         ctx->nlast_block += nleft;
205         /* If no more to process return */
206         if (dlen == 0)
207             return 1;
208         data += nleft;
209         /* Else not final block so encrypt it */
210         if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl))
211             return 0;
212     }
213     /* Encrypt all but one of the complete blocks left */
214     while (dlen > bl) {
215         if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl))
216             return 0;
217         dlen -= bl;
218         data += bl;
219     }
220     /* Copy any data left to last block buffer */
221     memcpy(ctx->last_block, data, dlen);
222     ctx->nlast_block = dlen;
223     return 1;
224
225 }
226
227 int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
228 {
229     int i, bl, lb;
230     if (ctx->nlast_block == -1)
231         return 0;
232     bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
233     *poutlen = (size_t)bl;
234     if (!out)
235         return 1;
236     lb = ctx->nlast_block;
237     /* Is last block complete? */
238     if (lb == bl) {
239         for (i = 0; i < bl; i++)
240             out[i] = ctx->last_block[i] ^ ctx->k1[i];
241     } else {
242         ctx->last_block[lb] = 0x80;
243         if (bl - lb > 1)
244             memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
245         for (i = 0; i < bl; i++)
246             out[i] = ctx->last_block[i] ^ ctx->k2[i];
247     }
248     if (!EVP_Cipher(ctx->cctx, out, out, bl)) {
249         OPENSSL_cleanse(out, bl);
250         return 0;
251     }
252     return 1;
253 }
254
255 int CMAC_resume(CMAC_CTX *ctx)
256 {
257     if (ctx->nlast_block == -1)
258         return 0;
259     /*
260      * The buffer "tbl" containes the last fully encrypted block which is the
261      * last IV (or all zeroes if no last encrypted block). The last block has
262      * not been modified since CMAC_final(). So reinitliasing using the last
263      * decrypted block will allow CMAC to continue after calling
264      * CMAC_Final().
265      */
266     return EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, ctx->tbl);
267 }