OpenCoverage

cmac.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/cmac/cmac.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: cmac.c,v 1.10 2015/09/10 15:56:25 jsing Exp $ */-
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-
58#include <openssl/cmac.h>-
59-
60struct 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-
75/* Make temporary keys K1 and K2 */-
76-
77static void-
78make_kn(unsigned char *k1, unsigned char *l, int bl)-
79{-
80 int i;-
81-
82 /* Shift block to left, including carry */-
83 for (i = 0; i < bl; i++) {
i < blDescription
TRUEnever evaluated
FALSEnever evaluated
0
84 k1[i] = l[i] << 1;-
85 if (i < bl - 1 && l[i + 1] & 0x80)
i < bl - 1Description
TRUEnever evaluated
FALSEnever evaluated
l[i + 1] & 0x80Description
TRUEnever evaluated
FALSEnever evaluated
0
86 k1[i] |= 1;
never executed: k1[i] |= 1;
0
87 }
never executed: end of block
0
88 /* If MSB set fixup with R */-
89 if (l[0] & 0x80)
l[0] & 0x80Description
TRUEnever evaluated
FALSEnever evaluated
0
90 k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
never executed: k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b;
bl == 16Description
TRUEnever evaluated
FALSEnever evaluated
0
91}
never executed: end of block
0
92-
93CMAC_CTX *-
94CMAC_CTX_new(void)-
95{-
96 CMAC_CTX *ctx;-
97-
98 ctx = malloc(sizeof(CMAC_CTX));-
99 if (!ctx)
!ctxDescription
TRUEnever evaluated
FALSEnever evaluated
0
100 return NULL;
never executed: return ((void *)0) ;
0
101 EVP_CIPHER_CTX_init(&ctx->cctx);-
102 ctx->nlast_block = -1;-
103 return ctx;
never executed: return ctx;
0
104}-
105-
106void-
107CMAC_CTX_cleanup(CMAC_CTX *ctx)-
108{-
109 EVP_CIPHER_CTX_cleanup(&ctx->cctx);-
110 explicit_bzero(ctx->tbl, EVP_MAX_BLOCK_LENGTH);-
111 explicit_bzero(ctx->k1, EVP_MAX_BLOCK_LENGTH);-
112 explicit_bzero(ctx->k2, EVP_MAX_BLOCK_LENGTH);-
113 explicit_bzero(ctx->last_block, EVP_MAX_BLOCK_LENGTH);-
114 ctx->nlast_block = -1;-
115}
never executed: end of block
0
116-
117EVP_CIPHER_CTX *-
118CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)-
119{-
120 return &ctx->cctx;
never executed: return &ctx->cctx;
0
121}-
122-
123void-
124CMAC_CTX_free(CMAC_CTX *ctx)-
125{-
126 if (ctx == NULL)
ctx == ((void *)0)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • freenull
FALSEnever evaluated
0-1
127 return;
executed 1 time by 1 test: return;
Executed by:
  • freenull
1
128-
129 CMAC_CTX_cleanup(ctx);-
130 free(ctx);-
131}
never executed: end of block
0
132-
133int-
134CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)-
135{-
136 int bl;-
137-
138 if (in->nlast_block == -1)
in->nlast_block == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
139 return 0;
never executed: return 0;
0
140 if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx))
!EVP_CIPHER_CT...tx, &in->cctx)Description
TRUEnever evaluated
FALSEnever evaluated
0
141 return 0;
never executed: return 0;
0
142 bl = EVP_CIPHER_CTX_block_size(&in->cctx);-
143 memcpy(out->k1, in->k1, bl);-
144 memcpy(out->k2, in->k2, bl);-
145 memcpy(out->tbl, in->tbl, bl);-
146 memcpy(out->last_block, in->last_block, bl);-
147 out->nlast_block = in->nlast_block;-
148 return 1;
never executed: return 1;
0
149}-
150-
151int-
152CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,-
153 const EVP_CIPHER *cipher, ENGINE *impl)-
154{-
155 static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH];-
156-
157 /* All zeros means restart */-
158 if (!key && !cipher && !impl && keylen == 0) {
!keyDescription
TRUEnever evaluated
FALSEnever evaluated
!cipherDescription
TRUEnever evaluated
FALSEnever evaluated
!implDescription
TRUEnever evaluated
FALSEnever evaluated
keylen == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
159 /* Not initialised */-
160 if (ctx->nlast_block == -1)
ctx->nlast_block == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
161 return 0;
never executed: return 0;
0
162 if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
!EVP_EncryptIn...)0) , zero_iv)Description
TRUEnever evaluated
FALSEnever evaluated
0
163 return 0;
never executed: return 0;
0
164 memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));-
165 ctx->nlast_block = 0;-
166 return 1;
never executed: return 1;
0
167 }-
168 /* Initialiase context */-
169 if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL))
cipherDescription
TRUEnever evaluated
FALSEnever evaluated
!EVP_EncryptIn... ((void *)0) )Description
TRUEnever evaluated
FALSEnever evaluated
0
170 return 0;
never executed: return 0;
0
171 /* Non-NULL key means initialisation complete */-
172 if (key) {
keyDescription
TRUEnever evaluated
FALSEnever evaluated
0
173 int bl;-
174-
175 if (!EVP_CIPHER_CTX_cipher(&ctx->cctx))
!EVP_CIPHER_CT...er(&ctx->cctx)Description
TRUEnever evaluated
FALSEnever evaluated
0
176 return 0;
never executed: return 0;
0
177 if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen))
!EVP_CIPHER_CT...>cctx, keylen)Description
TRUEnever evaluated
FALSEnever evaluated
0
178 return 0;
never executed: return 0;
0
179 if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv))
!EVP_EncryptIn... key, zero_iv)Description
TRUEnever evaluated
FALSEnever evaluated
0
180 return 0;
never executed: return 0;
0
181 bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);-
182 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl))
!EVP_Cipher(&c..., zero_iv, bl)Description
TRUEnever evaluated
FALSEnever evaluated
0
183 return 0;
never executed: return 0;
0
184 make_kn(ctx->k1, ctx->tbl, bl);-
185 make_kn(ctx->k2, ctx->k1, bl);-
186 explicit_bzero(ctx->tbl, bl);-
187 /* Reset context again ready for first data block */-
188 if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
!EVP_EncryptIn...)0) , zero_iv)Description
TRUEnever evaluated
FALSEnever evaluated
0
189 return 0;
never executed: return 0;
0
190 /* Zero tbl so resume works */-
191 memset(ctx->tbl, 0, bl);-
192 ctx->nlast_block = 0;-
193 }
never executed: end of block
0
194 return 1;
never executed: return 1;
0
195}-
196-
197int-
198CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)-
199{-
200 const unsigned char *data = in;-
201 size_t bl;-
202-
203 if (ctx->nlast_block == -1)
ctx->nlast_block == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
204 return 0;
never executed: return 0;
0
205 if (dlen == 0)
dlen == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
206 return 1;
never executed: return 1;
0
207 bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);-
208 /* Copy into partial block if we need to */-
209 if (ctx->nlast_block > 0) {
ctx->nlast_block > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
210 size_t nleft;-
211-
212 nleft = bl - ctx->nlast_block;-
213 if (dlen < nleft)
dlen < nleftDescription
TRUEnever evaluated
FALSEnever evaluated
0
214 nleft = dlen;
never executed: nleft = dlen;
0
215 memcpy(ctx->last_block + ctx->nlast_block, data, nleft);-
216 dlen -= nleft;-
217 ctx->nlast_block += nleft;-
218 /* If no more to process return */-
219 if (dlen == 0)
dlen == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
220 return 1;
never executed: return 1;
0
221 data += nleft;-
222 /* Else not final block so encrypt it */-
223 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl))
!EVP_Cipher(&c...ast_block, bl)Description
TRUEnever evaluated
FALSEnever evaluated
0
224 return 0;
never executed: return 0;
0
225 }
never executed: end of block
0
226 /* Encrypt all but one of the complete blocks left */-
227 while (dlen > bl) {
dlen > blDescription
TRUEnever evaluated
FALSEnever evaluated
0
228 if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl))
!EVP_Cipher(&c...tbl, data, bl)Description
TRUEnever evaluated
FALSEnever evaluated
0
229 return 0;
never executed: return 0;
0
230 dlen -= bl;-
231 data += bl;-
232 }
never executed: end of block
0
233 /* Copy any data left to last block buffer */-
234 memcpy(ctx->last_block, data, dlen);-
235 ctx->nlast_block = dlen;-
236 return 1;
never executed: return 1;
0
237}-
238-
239int-
240CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)-
241{-
242 int i, bl, lb;-
243-
244 if (ctx->nlast_block == -1)
ctx->nlast_block == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
245 return 0;
never executed: return 0;
0
246 bl = EVP_CIPHER_CTX_block_size(&ctx->cctx);-
247 *poutlen = (size_t)bl;-
248 if (!out)
!outDescription
TRUEnever evaluated
FALSEnever evaluated
0
249 return 1;
never executed: return 1;
0
250 lb = ctx->nlast_block;-
251 /* Is last block complete? */-
252 if (lb == bl) {
lb == blDescription
TRUEnever evaluated
FALSEnever evaluated
0
253 for (i = 0; i < bl; i++)
i < blDescription
TRUEnever evaluated
FALSEnever evaluated
0
254 out[i] = ctx->last_block[i] ^ ctx->k1[i];
never executed: out[i] = ctx->last_block[i] ^ ctx->k1[i];
0
255 } else {
never executed: end of block
0
256 ctx->last_block[lb] = 0x80;-
257 if (bl - lb > 1)
bl - lb > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
258 memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
never executed: memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
0
259 for (i = 0; i < bl; i++)
i < blDescription
TRUEnever evaluated
FALSEnever evaluated
0
260 out[i] = ctx->last_block[i] ^ ctx->k2[i];
never executed: out[i] = ctx->last_block[i] ^ ctx->k2[i];
0
261 }
never executed: end of block
0
262 if (!EVP_Cipher(&ctx->cctx, out, out, bl)) {
!EVP_Cipher(&c... out, out, bl)Description
TRUEnever evaluated
FALSEnever evaluated
0
263 explicit_bzero(out, bl);-
264 return 0;
never executed: return 0;
0
265 }-
266 return 1;
never executed: return 1;
0
267}-
268-
269int-
270CMAC_resume(CMAC_CTX *ctx)-
271{-
272 if (ctx->nlast_block == -1)
ctx->nlast_block == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
273 return 0;
never executed: return 0;
0
274 /* The buffer "tbl" containes the last fully encrypted block-
275 * which is the last IV (or all zeroes if no last encrypted block).-
276 * The last block has not been modified since CMAC_final().-
277 * So reinitialising using the last decrypted block will allow-
278 * CMAC to continue after calling CMAC_Final().-
279 */-
280 return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl);
never executed: return EVP_EncryptInit_ex(&ctx->cctx, ((void *)0) , ((void *)0) , ((void *)0) , ctx->tbl);
0
281}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2