2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
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/)"
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.
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.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
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 * ====================================================================
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
59 #define OPENSSL_FIPSAPI
64 #include <openssl/bio.h>
65 #include <openssl/evp.h>
66 #include <openssl/cmac.h>
67 #include <openssl/err.h>
68 #include <openssl/bn.h>
72 int main(int argc, char *argv[])
74 printf("No FIPS CMAC support\n");
80 #include <openssl/fips.h>
83 static int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in,
84 int mode, int Klen_counts_keys, int known_keylen);
85 static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
86 unsigned char *Key, int Klen,
87 unsigned char *Msg, int Msglen,
89 static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
90 unsigned char *Key, int Klen,
91 unsigned char *Msg, int Msglen,
92 unsigned char *Mac, int Maclen,
96 int fips_cmactest_main(int argc, char **argv)
98 int main(int argc, char **argv)
101 FILE *in = NULL, *out = NULL;
102 int mode = 0; /* 0 => Generate, 1 => Verify */
103 int Klen_counts_keys = 0; /* 0 => Klen is size of one key
104 1 => Klen is amount of keys
106 int known_keylen = 0; /* Only set when Klen_counts_keys = 1 */
107 const EVP_CIPHER *cipher = 0;
111 while (argc > 1 && argv[1][0] == '-')
117 char *p = &argv[1][2];
122 fprintf(stderr, "Option %s needs a value\n", argv[1]);
129 if (!strcmp(p, "aes128"))
130 cipher = EVP_aes_128_cbc();
131 else if (!strcmp(p, "aes192"))
132 cipher = EVP_aes_192_cbc();
133 else if (!strcmp(p, "aes256"))
134 cipher = EVP_aes_256_cbc();
135 else if (!strcmp(p, "tdea3") || !strcmp(p, "tdes3"))
137 cipher = EVP_des_ede3_cbc();
138 Klen_counts_keys = 1;
143 fprintf(stderr, "Unknown algorithm %s\n", p);
155 fprintf(stderr, "Unknown option %s\n", argv[1]);
164 in = fopen(argv[1], "r");
169 out = fopen(argv[2], "w");
173 fprintf(stderr, "FATAL input initialization error\n");
179 fprintf(stderr, "FATAL output initialization error\n");
183 if (!cmac_test(cipher, out, in, mode,
184 Klen_counts_keys, known_keylen))
186 fprintf(stderr, "FATAL cmac file processing error\n");
194 if (in && (in != stdin))
196 if (out && (out != stdout))
203 #define CMAC_TEST_MAXLINELEN 150000
205 int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in,
206 int mode, int Klen_counts_keys, int known_keylen)
208 char *linebuf, *olinebuf, *p, *q;
209 char *keyword, *value;
210 unsigned char **Keys = NULL, *Msg = NULL, *Mac = NULL;
211 unsigned char *Key = NULL;
212 int Count, Klen, Mlen, Tlen;
213 long Keylen, Msglen, Maclen;
217 olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
218 linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
220 if (!linebuf || !olinebuf)
228 while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in))
231 strcpy(linebuf, olinebuf);
233 /* Skip leading space */
234 while (isspace((unsigned char)*keyword))
238 if (keyword[0] == '#')
240 if (fputs(olinebuf, out) < 0)
245 /* Look for = sign */
246 p = strchr(linebuf, '=');
248 /* If no = or starts with [ (for [L=20] line) just copy */
251 if (fputs(olinebuf, out) < 0)
258 /* Remove trailing space */
259 while (isspace((unsigned char)*q))
265 /* Remove leading space from value */
266 while (isspace((unsigned char)*value))
269 /* Remove trailing space from value */
270 p = value + strlen(value) - 1;
272 while (*p == '\n' || isspace((unsigned char)*p))
275 if (!strcmp(keyword, "Count"))
283 else if (!strcmp(keyword, "Klen"))
290 if (Klen_counts_keys)
292 Keys = OPENSSL_malloc(sizeof(*Keys) * Klen);
293 memset(Keys, '\0', sizeof(*Keys) * Klen);
297 Keys = OPENSSL_malloc(sizeof(*Keys));
298 memset(Keys, '\0', sizeof(*Keys));
301 else if (!strcmp(keyword, "Mlen"))
309 else if (!strcmp(keyword, "Tlen"))
317 else if (!strcmp(keyword, "Key") && !Klen_counts_keys)
321 Keys[0] = hex2bin_m(value, &Keylen);
325 else if (!strncmp(keyword, "Key", 3) && Klen_counts_keys)
327 int keynum = atoi(keyword + 3);
328 if (!keynum || keynum > Klen || Keys[keynum-1])
330 Keys[keynum-1] = hex2bin_m(value, &Keylen);
334 else if (!strcmp(keyword, "Msg"))
338 Msg = hex2bin_m(value, &Msglen);
342 else if (!strcmp(keyword, "Mac"))
348 Mac = hex2bin_m(value, &Maclen);
352 else if (!strcmp(keyword, "Result"))
361 fputs(olinebuf, out);
363 if (Keys && Msg && (!mode || Mac) && (Tlen > 0) && (Klen > 0))
365 if (Klen_counts_keys)
368 Key = OPENSSL_malloc(Klen * known_keylen);
369 for (x = 0; x < Klen; x++)
371 memcpy(Key + x * known_keylen,
372 Keys[x], known_keylen);
373 OPENSSL_free(Keys[x]);
375 Klen *= known_keylen;
379 Key = OPENSSL_malloc(Klen);
380 memcpy(Key, Keys[0], Klen);
381 OPENSSL_free(Keys[0]);
388 if (!print_cmac_gen(cipher, out,
395 if (!print_cmac_ver(cipher, out,
424 OPENSSL_free(olinebuf);
426 OPENSSL_free(linebuf);
438 fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
444 static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
445 unsigned char *Key, int Klen,
446 unsigned char *Msg, int Mlen,
451 unsigned char res[128];
452 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
454 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
455 CMAC_Update(cmac_ctx, Msg, Mlen);
456 if (!CMAC_Final(cmac_ctx, res, &reslen))
458 fputs("Error calculating CMAC\n", stderr);
461 else if (Tlen > (int)reslen)
463 fputs("Parameter error, Tlen > CMAC length\n", stderr);
468 fputs("Mac = ", out);
469 for (i = 0; i < Tlen; i++)
470 fprintf(out, "%02x", res[i]);
471 fputs(RESP_EOL, out);
474 CMAC_CTX_free(cmac_ctx);
478 static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
479 unsigned char *Key, int Klen,
480 unsigned char *Msg, int Mlen,
481 unsigned char *Mac, int Maclen,
486 unsigned char res[128];
487 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
489 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
490 CMAC_Update(cmac_ctx, Msg, Mlen);
491 if (!CMAC_Final(cmac_ctx, res, &reslen))
493 fputs("Error calculating CMAC\n", stderr);
496 else if (Tlen > (int)reslen)
498 fputs("Parameter error, Tlen > CMAC length\n", stderr);
501 else if (Tlen != Maclen)
503 fputs("Parameter error, Tlen != resulting Mac length\n", stderr);
508 if (!memcmp(Mac, res, Maclen))
509 fputs("Result = P" RESP_EOL, out);
511 fputs("Result = F" RESP_EOL, out);
513 CMAC_CTX_free(cmac_ctx);