iPXE
hmac.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 *
23 * Alternatively, you may distribute this code in source or binary
24 * form, with or without modification, provided that the following
25 * conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the above disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above
31 * copyright notice, this list of conditions and the above
32 * disclaimer in the documentation and/or other materials provided
33 * with the distribution.
34 */
35
36FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
37FILE_SECBOOT ( PERMITTED );
38
39/**
40 * @file
41 *
42 * Keyed-Hashing for Message Authentication
43 */
44
45#include <string.h>
46#include <assert.h>
47#include <ipxe/crypto.h>
48#include <ipxe/hmac.h>
49
50/**
51 * Construct HMAC reduced key
52 *
53 * @v digest Digest algorithm to use
54 * @v ctx HMAC context
55 * @v secret Secret key
56 * @v len Length of secret key
57 * @v key HMAC reduced key to fill in
58 */
59void hmac_key ( struct digest_algorithm *digest, void *ctx, const void *secret,
60 size_t len, void *key ) {
61 hmac_context_t ( digest ) *hctx = ctx;
62 hmac_key_t ( digest ) *hkey = key;
63
64 /* Reduce key (if applicable) and zero-pad to block size */
65 memset ( hkey->pad, 0, sizeof ( hkey->pad ) );
66 if ( len <= sizeof ( hkey->pad ) ) {
67 memcpy ( hkey->pad, secret, len );
68 } else {
69 digest_init ( digest, hctx->ctx );
70 digest_update ( digest, hctx->ctx, secret, len );
71 digest_final ( digest, hctx->ctx, hkey->pad );
72 }
73}
74
75/**
76 * Initialise HMAC from reduced key
77 *
78 * @v digest Digest algorithm
79 * @v ctx HMAC context
80 * @v hkey HMAC key
81 */
82void hmac_init_key ( struct digest_algorithm *digest, void *ctx,
83 const void *key ) {
84 hmac_context_t ( digest ) *hctx = ctx;
85 const hmac_key_t ( digest ) *hkey = key;
86 unsigned int i;
87
88 /* Construct input pad */
89 for ( i = 0 ; i < sizeof ( hkey->pad ) ; i++ ) {
90 hctx->pad[i] = ( hkey->pad[i] ^ 0x36 );
91 }
92
93 /* Start inner hash */
94 digest_init ( digest, hctx->ctx );
95 digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
96}
97
98/**
99 * Initialise HMAC
100 *
101 * @v digest Digest algorithm to use
102 * @v ctx HMAC context
103 * @v secret Secret key
104 * @v len Length of secret key
105 */
106void hmac_init ( struct digest_algorithm *digest, void *ctx,
107 const void *secret, size_t len ) {
108 hmac_context_t ( digest ) *hctx = ctx;
109
110 /* Construct reduced key (in input pad) */
111 hmac_key ( digest, hctx->ctx, secret, len, hctx->pad );
112
113 /* Initialise HMAC */
114 hmac_init_key ( digest, hctx->ctx, hctx->pad );
115}
116
117/**
118 * Finalise HMAC
119 *
120 * @v digest Digest algorithm to use
121 * @v ctx HMAC context
122 * @v hmac HMAC digest to fill in
123 */
124void hmac_final ( struct digest_algorithm *digest, void *ctx, void *hmac ) {
125 hmac_context_t ( digest ) *hctx = ctx;
126 unsigned int i;
127
128 /* Construct output pad from input pad */
129 for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
130 hctx->pad[i] ^= 0x6a;
131 }
132
133 /* Finish inner hash */
134 digest_final ( digest, hctx->ctx, hmac );
135
136 /* Perform outer hash */
137 digest_init ( digest, hctx->ctx );
138 digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
139 digest_update ( digest, hctx->ctx, hmac, digest->digestsize );
140 digest_final ( digest, hctx->ctx, hmac );
141
142 /* Erase output pad (from which the key may be derivable) */
143 memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
144}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
union @162305117151260234136356364136041353210355154177 key
Assertions.
ring len
Length.
Definition dwmac.h:226
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
void hmac_init(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len)
Initialise HMAC.
Definition hmac.c:106
void hmac_final(struct digest_algorithm *digest, void *ctx, void *hmac)
Finalise HMAC.
Definition hmac.c:124
void hmac_key(struct digest_algorithm *digest, void *ctx, const void *secret, size_t len, void *key)
Construct HMAC reduced key.
Definition hmac.c:59
void hmac_init_key(struct digest_algorithm *digest, void *ctx, const void *key)
Initialise HMAC from reduced key.
Definition hmac.c:82
Keyed-Hashing for Message Authentication.
#define hmac_key_t(digest)
HMAC reduced key type.
Definition hmac.h:15
#define hmac_context_t(digest)
HMAC context type.
Definition hmac.h:21
Cryptographic API.
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:294
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:305
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:299
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
A message digest algorithm.
Definition crypto.h:19
size_t digestsize
Digest size.
Definition crypto.h:27