1193645Ssimon/* ====================================================================
2193645Ssimon * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
3193645Ssimon *
4193645Ssimon * Redistribution and use in source and binary forms, with or without
5193645Ssimon * modification, are permitted provided that the following conditions
6193645Ssimon * are met:
7193645Ssimon *
8193645Ssimon * 1. Redistributions of source code must retain the above copyright
9296465Sdelphij *    notice, this list of conditions and the following disclaimer.
10193645Ssimon *
11193645Ssimon * 2. Redistributions in binary form must reproduce the above copyright
12193645Ssimon *    notice, this list of conditions and the following disclaimer in
13193645Ssimon *    the documentation and/or other materials provided with the
14193645Ssimon *    distribution.
15193645Ssimon *
16193645Ssimon * 3. All advertising materials mentioning features or use of this
17193645Ssimon *    software must display the following acknowledgment:
18193645Ssimon *    "This product includes software developed by the OpenSSL Project
19193645Ssimon *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20193645Ssimon *
21193645Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22193645Ssimon *    endorse or promote products derived from this software without
23193645Ssimon *    prior written permission. For written permission, please contact
24193645Ssimon *    openssl-core@openssl.org.
25193645Ssimon *
26193645Ssimon * 5. Products derived from this software may not be called "OpenSSL"
27193645Ssimon *    nor may "OpenSSL" appear in their names without prior written
28193645Ssimon *    permission of the OpenSSL Project.
29193645Ssimon *
30193645Ssimon * 6. Redistributions of any form whatsoever must retain the following
31193645Ssimon *    acknowledgment:
32193645Ssimon *    "This product includes software developed by the OpenSSL Project
33193645Ssimon *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34193645Ssimon *
35193645Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36193645Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37193645Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38193645Ssimon * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
39193645Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40193645Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41193645Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42193645Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43193645Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44193645Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45193645Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46193645Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE.
47193645Ssimon *
48193645Ssimon */
49193645Ssimon
50193645Ssimon#include <stdio.h>
51193645Ssimon#include <stdlib.h>
52193645Ssimon#include <string.h>
53193645Ssimon#include <openssl/opensslconf.h>
54193645Ssimon#include <openssl/sha.h>
55193645Ssimon#include <openssl/hmac.h>
56193645Ssimon
57193645Ssimon#ifndef FIPSCANISTER_O
58296465Sdelphijint FIPS_selftest_failed()
59296465Sdelphij{
60296465Sdelphij    return 0;
61296465Sdelphij}
62296465Sdelphij
63296465Sdelphijvoid FIPS_selftest_check()
64296465Sdelphij{
65296465Sdelphij}
66296465Sdelphij
67296465Sdelphijvoid OPENSSL_cleanse(void *p, size_t len)
68296465Sdelphij{
69296465Sdelphij}
70193645Ssimon#endif
71193645Ssimon
72193645Ssimon#ifdef OPENSSL_FIPS
73193645Ssimon
74296465Sdelphijstatic void hmac_init(SHA_CTX *md_ctx, SHA_CTX *o_ctx, const char *key)
75296465Sdelphij{
76296465Sdelphij    size_t len = strlen(key);
77193645Ssimon    int i;
78193645Ssimon    unsigned char keymd[HMAC_MAX_MD_CBLOCK];
79193645Ssimon    unsigned char pad[HMAC_MAX_MD_CBLOCK];
80193645Ssimon
81296465Sdelphij    if (len > SHA_CBLOCK) {
82296465Sdelphij        SHA1_Init(md_ctx);
83296465Sdelphij        SHA1_Update(md_ctx, key, len);
84296465Sdelphij        SHA1_Final(keymd, md_ctx);
85296465Sdelphij        len = 20;
86296465Sdelphij    } else
87296465Sdelphij        memcpy(keymd, key, len);
88296465Sdelphij    memset(&keymd[len], '\0', HMAC_MAX_MD_CBLOCK - len);
89193645Ssimon
90296465Sdelphij    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
91296465Sdelphij        pad[i] = 0x36 ^ keymd[i];
92193645Ssimon    SHA1_Init(md_ctx);
93296465Sdelphij    SHA1_Update(md_ctx, pad, SHA_CBLOCK);
94193645Ssimon
95296465Sdelphij    for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
96296465Sdelphij        pad[i] = 0x5c ^ keymd[i];
97193645Ssimon    SHA1_Init(o_ctx);
98296465Sdelphij    SHA1_Update(o_ctx, pad, SHA_CBLOCK);
99296465Sdelphij}
100193645Ssimon
101296465Sdelphijstatic void hmac_final(unsigned char *md, SHA_CTX *md_ctx, SHA_CTX *o_ctx)
102296465Sdelphij{
103193645Ssimon    unsigned char buf[20];
104193645Ssimon
105296465Sdelphij    SHA1_Final(buf, md_ctx);
106296465Sdelphij    SHA1_Update(o_ctx, buf, sizeof buf);
107296465Sdelphij    SHA1_Final(md, o_ctx);
108296465Sdelphij}
109193645Ssimon
110193645Ssimon#endif
111193645Ssimon
112296465Sdelphijint main(int argc, char **argv)
113296465Sdelphij{
114193645Ssimon#ifdef OPENSSL_FIPS
115296465Sdelphij    static char key[] = "etaonrishdlcupfm";
116296465Sdelphij    int n, binary = 0;
117193645Ssimon
118296465Sdelphij    if (argc < 2) {
119296465Sdelphij        fprintf(stderr, "%s [<file>]+\n", argv[0]);
120296465Sdelphij        exit(1);
121296465Sdelphij    }
122193645Ssimon
123296465Sdelphij    n = 1;
124296465Sdelphij    if (!strcmp(argv[n], "-binary")) {
125296465Sdelphij        n++;
126296465Sdelphij        binary = 1;             /* emit binary fingerprint... */
127296465Sdelphij    }
128193645Ssimon
129296465Sdelphij    for (; n < argc; ++n) {
130296465Sdelphij        FILE *f = fopen(argv[n], "rb");
131296465Sdelphij        SHA_CTX md_ctx, o_ctx;
132296465Sdelphij        unsigned char md[20];
133296465Sdelphij        int i;
134193645Ssimon
135296465Sdelphij        if (!f) {
136296465Sdelphij            perror(argv[n]);
137296465Sdelphij            exit(2);
138296465Sdelphij        }
139193645Ssimon
140296465Sdelphij        hmac_init(&md_ctx, &o_ctx, key);
141296465Sdelphij        for (;;) {
142296465Sdelphij            char buf[1024];
143296465Sdelphij            size_t l = fread(buf, 1, sizeof buf, f);
144193645Ssimon
145296465Sdelphij            if (l == 0) {
146296465Sdelphij                if (ferror(f)) {
147296465Sdelphij                    perror(argv[n]);
148296465Sdelphij                    exit(3);
149296465Sdelphij                } else
150296465Sdelphij                    break;
151296465Sdelphij            }
152296465Sdelphij            SHA1_Update(&md_ctx, buf, l);
153296465Sdelphij        }
154296465Sdelphij        hmac_final(md, &md_ctx, &o_ctx);
155193645Ssimon
156296465Sdelphij        if (binary) {
157296465Sdelphij            fwrite(md, 20, 1, stdout);
158296465Sdelphij            break;              /* ... for single(!) file */
159296465Sdelphij        }
160193645Ssimon
161296465Sdelphij        printf("HMAC-SHA1(%s)= ", argv[n]);
162296465Sdelphij        for (i = 0; i < 20; ++i)
163296465Sdelphij            printf("%02x", md[i]);
164296465Sdelphij        printf("\n");
165296465Sdelphij    }
166193645Ssimon#endif
167193645Ssimon    return 0;
168296465Sdelphij}
169