blob: 9fa569d026da6c04759cdc6a0433278377433e49 [file] [log] [blame]
nagendra modadugu4fae5422016-05-10 16:11:54 -07001// Copyright 2016 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#include "cryptoc/hmac.h"
nagendra modadugu7c350b92016-10-18 15:13:05 -070015#include "cryptoc/util.h"
nagendra modadugu4fae5422016-05-10 16:11:54 -070016
17#include <string.h>
18#include "cryptoc/sha.h"
19#include "cryptoc/md5.h"
nagendra modadugu793cf592019-10-09 14:07:05 -070020#include "cryptoc/sha224.h"
nagendra modadugu4fae5422016-05-10 16:11:54 -070021#include "cryptoc/sha256.h"
nagendra modadugu793cf592019-10-09 14:07:05 -070022#include "cryptoc/sha384.h"
23#include "cryptoc/sha512.h"
nagendra modadugu4fae5422016-05-10 16:11:54 -070024
25static void HMAC_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
26 unsigned int i;
27 memset(&ctx->opad[0], 0, sizeof(ctx->opad));
28
nagendra modadugu793cf592019-10-09 14:07:05 -070029 if (len > HASH_block_size(&ctx->hash)) {
nagendra modadugu4fae5422016-05-10 16:11:54 -070030 HASH_init(&ctx->hash);
31 HASH_update(&ctx->hash, key, len);
32 memcpy(&ctx->opad[0], HASH_final(&ctx->hash), HASH_size(&ctx->hash));
33 } else {
34 memcpy(&ctx->opad[0], key, len);
35 }
36
nagendra modadugu793cf592019-10-09 14:07:05 -070037 for (i = 0; i < HASH_block_size(&ctx->hash); ++i) {
nagendra modadugu4fae5422016-05-10 16:11:54 -070038 ctx->opad[i] ^= 0x36;
39 }
40
41 HASH_init(&ctx->hash);
nagendra modadugu793cf592019-10-09 14:07:05 -070042 HASH_update(&ctx->hash, ctx->opad, HASH_block_size(&ctx->hash)); // hash ipad
nagendra modadugu4fae5422016-05-10 16:11:54 -070043
nagendra modadugu793cf592019-10-09 14:07:05 -070044 for (i = 0; i < HASH_block_size(&ctx->hash); ++i) {
nagendra modadugu4fae5422016-05-10 16:11:54 -070045 ctx->opad[i] ^= (0x36 ^ 0x5c);
46 }
47}
48
49void HMAC_MD5_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
50 MD5_init(&ctx->hash);
51 HMAC_init(ctx, key, len);
52}
53
54void HMAC_SHA_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
55 SHA_init(&ctx->hash);
56 HMAC_init(ctx, key, len);
57}
58
nagendra modadugu793cf592019-10-09 14:07:05 -070059void HMAC_SHA224_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
60 SHA224_init(&ctx->hash);
61 HMAC_init(ctx, key, len);
62}
63
nagendra modadugu4fae5422016-05-10 16:11:54 -070064void HMAC_SHA256_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
65 SHA256_init(&ctx->hash);
66 HMAC_init(ctx, key, len);
67}
68
nagendra modadugu793cf592019-10-09 14:07:05 -070069#ifdef SHA512_SUPPORT
70void HMAC_SHA384_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
71 SHA384_init(&ctx->hash);
72 HMAC_init(ctx, key, len);
73}
74
75void HMAC_SHA512_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
76 SHA512_init(&ctx->hash);
77 HMAC_init(ctx, key, len);
78}
79#endif
80
nagendra modadugu4fae5422016-05-10 16:11:54 -070081const uint8_t* HMAC_final(LITE_HMAC_CTX* ctx) {
nagendra modadugu793cf592019-10-09 14:07:05 -070082#ifndef SHA512_SUPPORT
83 uint8_t digest[32]; // upto SHA2-256
84#else
85 uint8_t digest[64]; // upto SHA2-512
86#endif
nagendra modadugu4fae5422016-05-10 16:11:54 -070087 memcpy(digest, HASH_final(&ctx->hash),
88 (HASH_size(&ctx->hash) <= sizeof(digest) ?
89 HASH_size(&ctx->hash) : sizeof(digest)));
90 HASH_init(&ctx->hash);
nagendra modadugu793cf592019-10-09 14:07:05 -070091 HASH_update(&ctx->hash, ctx->opad, HASH_block_size(&ctx->hash));
nagendra modadugu4fae5422016-05-10 16:11:54 -070092 HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
nagendra modadugu7c350b92016-10-18 15:13:05 -070093 always_memset(&ctx->opad[0], 0, sizeof(ctx->opad)); // wipe key
nagendra modadugu4fae5422016-05-10 16:11:54 -070094 return HASH_final(&ctx->hash);
95}