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, int mode);
84 static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
85 unsigned char *Key, int Klen,
86 unsigned char *Msg, int Msglen,
88 static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
89 unsigned char *Key, int Klen,
90 unsigned char *Msg, int Msglen,
91 unsigned char *Mac, int Maclen,
94 int main(int argc, char **argv)
96 FILE *in = NULL, *out = NULL;
97 int mode = 0; /* 0 => Generate, 1 => Verify */
100 fips_set_error_print();
101 if(!FIPS_mode_set(1))
104 if (argc > 1 && argv[1][0] == '-')
106 if (strcmp(argv[1], "-g") == 0)
108 else if (strcmp(argv[1], "-v") == 0)
112 fprintf(stderr, "Unknown option %s\n", argv[1]);
121 in = fopen(argv[1], "r");
126 out = fopen(argv[2], "w");
130 fprintf(stderr, "FATAL input initialization error\n");
136 fprintf(stderr, "FATAL output initialization error\n");
140 if (!cmac_test(EVP_aes_256_cbc(), out, in, mode))
142 fprintf(stderr, "FATAL cmac file processing error\n");
150 if (in && (in != stdin))
152 if (out && (out != stdout))
159 #define CMAC_TEST_MAXLINELEN 1024
161 int cmac_test(const EVP_CIPHER *cipher, FILE *out, FILE *in, int mode)
163 char *linebuf, *olinebuf, *p, *q;
164 char *keyword, *value;
165 unsigned char *Key = NULL, *Msg = NULL, *Mac = NULL;
166 int Count, Klen, Mlen, Tlen;
167 long Keylen, Msglen, Maclen;
171 olinebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
172 linebuf = OPENSSL_malloc(CMAC_TEST_MAXLINELEN);
174 if (!linebuf || !olinebuf)
182 while (fgets(olinebuf, CMAC_TEST_MAXLINELEN, in))
185 strcpy(linebuf, olinebuf);
187 /* Skip leading space */
188 while (isspace((unsigned char)*keyword))
192 if (keyword[0] == '#')
194 if (fputs(olinebuf, out) < 0)
199 /* Look for = sign */
200 p = strchr(linebuf, '=');
202 /* If no = or starts with [ (for [L=20] line) just copy */
205 if (fputs(olinebuf, out) < 0)
212 /* Remove trailing space */
213 while (isspace((unsigned char)*q))
219 /* Remove leading space from value */
220 while (isspace((unsigned char)*value))
223 /* Remove trailing space from value */
224 p = value + strlen(value) - 1;
226 while (*p == '\n' || isspace((unsigned char)*p))
229 if (!strcmp(keyword, "Count"))
237 else if (!strcmp(keyword, "Klen"))
245 else if (!strcmp(keyword, "Mlen"))
253 else if (!strcmp(keyword, "Tlen"))
261 else if (!strcmp(keyword, "Key"))
265 Key = hex2bin_m(value, &Keylen);
269 else if (!strcmp(keyword, "Msg"))
273 Msg = hex2bin_m(value, &Msglen);
277 else if (!strcmp(keyword, "Mac"))
283 Mac = hex2bin_m(value, &Maclen);
287 else if (!strcmp(keyword, "Result"))
296 fputs(olinebuf, out);
301 if (Key && Msg && (Tlen > 0) && (Klen > 0))
303 if (!print_cmac_gen(cipher, out,
319 if (Key && Msg && Mac && (Tlen > 0) && (Klen > 0))
321 if (!print_cmac_ver(cipher, out,
350 OPENSSL_free(olinebuf);
352 OPENSSL_free(linebuf);
362 fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
368 static int print_cmac_gen(const EVP_CIPHER *cipher, FILE *out,
369 unsigned char *Key, int Klen,
370 unsigned char *Msg, int Mlen,
375 unsigned char res[1024];
376 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
378 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
379 CMAC_Update(cmac_ctx, Msg, Mlen);
380 if (!CMAC_Final(cmac_ctx, res, &reslen))
382 fputs("Error calculating CMAC\n", stderr);
385 else if (Tlen > reslen)
387 fputs("Parameter error, Tlen > CMAC length\n", stderr);
392 fputs("Mac = ", out);
393 for (i = 0; i < Tlen; i++)
394 fprintf(out, "%02x", res[i]);
398 CMAC_CTX_free(cmac_ctx);
402 static int print_cmac_ver(const EVP_CIPHER *cipher, FILE *out,
403 unsigned char *Key, int Klen,
404 unsigned char *Msg, int Mlen,
405 unsigned char *Mac, int Maclen,
410 unsigned char res[1024];
411 CMAC_CTX *cmac_ctx = CMAC_CTX_new();
413 CMAC_Init(cmac_ctx, Key, Klen, cipher, 0);
414 CMAC_Update(cmac_ctx, Msg, Mlen);
415 if (!CMAC_Final(cmac_ctx, res, &reslen))
417 fputs("Error calculating CMAC\n", stderr);
420 else if (Tlen > reslen)
422 fputs("Parameter error, Tlen > CMAC length\n", stderr);
425 else if (Tlen != Maclen)
427 fputs("Parameter error, Tlen != resulting Mac length\n", stderr);
432 if (!memcmp(Mac, res, Maclen))
433 fputs("Result = P\n", out);
435 fputs("Result = F\n", out);
437 CMAC_CTX_free(cmac_ctx);