blob: f920c59b465cbfde2cbb2c1362dd39b3cda74756 [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 modadugu4fae5422016-05-10 16:11:54 -070015
16#include <string.h>
17#include "cryptoc/sha.h"
18#include "cryptoc/md5.h"
19#include "cryptoc/sha256.h"
20
21static void HMAC_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
22 unsigned int i;
23 memset(&ctx->opad[0], 0, sizeof(ctx->opad));
24
25 if (len > sizeof(ctx->opad)) {
26 HASH_init(&ctx->hash);
27 HASH_update(&ctx->hash, key, len);
28 memcpy(&ctx->opad[0], HASH_final(&ctx->hash), HASH_size(&ctx->hash));
29 } else {
30 memcpy(&ctx->opad[0], key, len);
31 }
32
33 for (i = 0; i < sizeof(ctx->opad); ++i) {
34 ctx->opad[i] ^= 0x36;
35 }
36
37 HASH_init(&ctx->hash);
38 HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad)); // hash ipad
39
40 for (i = 0; i < sizeof(ctx->opad); ++i) {
41 ctx->opad[i] ^= (0x36 ^ 0x5c);
42 }
43}
44
45void HMAC_MD5_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
46 MD5_init(&ctx->hash);
47 HMAC_init(ctx, key, len);
48}
49
50void HMAC_SHA_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
51 SHA_init(&ctx->hash);
52 HMAC_init(ctx, key, len);
53}
54
55void HMAC_SHA256_init(LITE_HMAC_CTX* ctx, const void* key, unsigned int len) {
56 SHA256_init(&ctx->hash);
57 HMAC_init(ctx, key, len);
58}
59
60const uint8_t* HMAC_final(LITE_HMAC_CTX* ctx) {
61 uint8_t digest[32]; // upto SHA2
62 memcpy(digest, HASH_final(&ctx->hash),
63 (HASH_size(&ctx->hash) <= sizeof(digest) ?
64 HASH_size(&ctx->hash) : sizeof(digest)));
65 HASH_init(&ctx->hash);
66 HASH_update(&ctx->hash, ctx->opad, sizeof(ctx->opad));
67 HASH_update(&ctx->hash, digest, HASH_size(&ctx->hash));
nagendra modadugu1510e372016-05-19 18:09:17 -070068 memset(&ctx->opad[0], 0, sizeof(ctx->opad)); // wipe key
nagendra modadugu4fae5422016-05-10 16:11:54 -070069 return HASH_final(&ctx->hash);
70}