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,
95 int main(int argc, char **argv)
97 FILE *in = NULL, *out = NULL;
98 int mode = 0; /* 0 => Generate, 1 => Verify */
99 int Klen_counts_keys = 0; /* 0 => Klen is size of one key
100 1 => Klen is amount of keys
102 int known_keylen = 0; /* Only set when Klen_counts_keys = 1 */
103 const EVP_CIPHER *cipher = 0;
105 fips_set_error_print();
106 if(!FIPS_mode_set(1))
109 while (argc > 1 && argv[1][0] == '-')
115 char *p = &argv[1][2];
120 fprintf(stderr, "Option %s needs a value\n", argv[1]);
127 if (!strcmp(p, "aes128"))
128 cipher = EVP_aes_128_cbc();
129 else if (!strcmp(p, "aes192"))
130 cipher = EVP_aes_192_cbc();
131 else if (!strcmp(p, "aes256"))
132 cipher = EVP_aes_256_cbc();
133 else if (!strcmp(p, "tdea3") || !strcmp(p, "tdes3"))
135 cipher = EVP_des_ede3_cbc();
136 Klen_counts_keys = 1;
141 fprintf(stderr, "Unknown algorithm %s\n", p);
153 fprintf(stderr, "Unknown option %s\n", argv[1]);
162 in = fopen(argv[1], "r");
167 out = fopen(argv[2], "w");
171 fprintf(stderr, "FATAL input initialization error\n");
177 fprintf(stderr, "FATAL output initialization error\n");
181 if (!cmac_test(cipher, out, in, mode,
182 Klen_counts_keys, known_keylen))
184 fprintf(stderr, "FATAL cmac file processing error\n");
192 if (in && (in != stdin))
194 if (out && (out != stdout))
201 #define CMAC_TEST_MAXLINELEN 150000
203 int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in,
204 int mode, int Klen_counts_keys, int known_keylen)
206 char *linebuf, *olinebuf, *p, *q;
207 char *keyword, *value;
208 unsigned char **Keys = NULL, *Msg = NULL, *Mac = NULL;
209 unsigned char *Key = NULL;
210 int Count, Klen, Mlen, Tlen;
211 long Keylen, Msglen, Maclen;
215 olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
216 linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
218 if (!linebuf || !olinebuf)
226 while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in))
229 strcpy(linebuf, olinebuf);
231 /* Skip leading space */
232 while (isspace((unsigned char)*keyword))
236 if (keyword[0] == '#')
238 if (fputs(olinebuf, out) < 0)
243 /* Look for = sign */
244 p = strchr(linebuf, '=');
246 /* If no = or starts with [ (for [L=20] line) just copy */
249 if (fputs(olinebuf, out) < 0)
256 /* Remove trailing space */
257 while (isspace((unsigned char)*q))
263 /* Remove leading space from value */
264 while (isspace((unsigned char)*value))
267 /* Remove trailing space from value */
268 p = value + strlen(value) - 1;
270 while (*p == '\n' || isspace((unsigned char)*p))
273 if (!strcmp(keyword, "Count"))
281 else if (!strcmp(keyword, "Klen"))
288 if (Klen_counts_keys)
290 Keys = OPENSSL_malloc(sizeof(*Keys) * Klen);
291 memset(Keys, '\0', sizeof(*Keys) * Klen);
295 Keys = OPENSSL_malloc(sizeof(*Keys));
296 memset(Keys, '\0', sizeof(*Keys));
299 else if (!strcmp(keyword, "Mlen"))
307 else if (!strcmp(keyword, "Tlen"))
315 else if (!strcmp(keyword, "Key") && !Klen_counts_keys)
319 Keys[0] = hex2bin_m(value, &Keylen);
323 else if (!strncmp(keyword, "Key", 3) && Klen_counts_keys)
325 int keynum = atoi(keyword + 3);
326 if (!keynum || keynum > Klen || Keys[keynum-1])
328 Keys[keynum-1] = hex2bin_m(value, &Keylen);
332 else if (!strcmp(keyword, "Msg"))
336 Msg = hex2bin_m(value, &Msglen);
340 else if (!strcmp(keyword, "Mac"))
346 Mac = hex2bin_m(value, &Maclen);
350 else if (!strcmp(keyword, "Result"))
359 fputs(olinebuf, out);
361 if (Keys && Msg && (!mode || Mac) && (Tlen > 0) && (Klen > 0))
363 if (Klen_counts_keys)
366 Key = OPENSSL_malloc(Klen * known_keylen);
367 for (x = 0; x < Klen; x++)
369 memcpy(Key + x * known_keylen,
370 Keys[x], known_keylen);
371 OPENSSL_free(Keys[x]);
373 Klen *= known_keylen;
377 Key = OPENSSL_malloc(Klen);
378 memcpy(Key, Keys[0], Klen);
379 OPENSSL_free(Keys[0]);
386 if (!print_cmac_gen(cipher, out,
393 if (!print_cmac_ver(cipher, out,
422 OPENSSL_free(olinebuf);
424 OPENSSL_free(linebuf);
436 fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
442 static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
443 unsigned char *Key, int Klen,
444 unsigned char *Msg, int Mlen,
449 unsigned char res[128];
450 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
452 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
453 CMAC_Update(cmac_ctx, Msg, Mlen);
454 if (!CMAC_Final(cmac_ctx, res, &reslen))
456 fputs("Error calculating CMAC\n", stderr);
459 else if (Tlen > (int)reslen)
461 fputs("Parameter error, Tlen > CMAC length\n", stderr);
466 fputs("Mac = ", out);
467 for (i = 0; i < Tlen; i++)
468 fprintf(out, "%02x", res[i]);
472 CMAC_CTX_free(cmac_ctx);
476 static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
477 unsigned char *Key, int Klen,
478 unsigned char *Msg, int Mlen,
479 unsigned char *Mac, int Maclen,
484 unsigned char res[128];
485 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
487 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
488 CMAC_Update(cmac_ctx, Msg, Mlen);
489 if (!CMAC_Final(cmac_ctx, res, &reslen))
491 fputs("Error calculating CMAC\n", stderr);
494 else if (Tlen > (int)reslen)
496 fputs("Parameter error, Tlen > CMAC length\n", stderr);
499 else if (Tlen != Maclen)
501 fputs("Parameter error, Tlen != resulting Mac length\n", stderr);
506 if (!memcmp(Mac, res, Maclen))
507 fputs("Result = P\n", out);
509 fputs("Result = F\n", out);
511 CMAC_CTX_free(cmac_ctx);