#include <ipxe/hmac.h>
/**
- * Initialise HMAC
+ * Construct HMAC reduced key
*
* @v digest Digest algorithm to use
* @v ctx HMAC context
- * @v key Key
- * @v key_len Length of key
+ * @v secret Secret key
+ * @v len Length of secret key
+ * @v key HMAC reduced key to fill in
*/
-void hmac_init ( struct digest_algorithm *digest, void *ctx, const void *key,
- size_t key_len ) {
+void hmac_key ( struct digest_algorithm *digest, void *ctx, const void *secret,
+ size_t len, void *key ) {
hmac_context_t ( digest ) *hctx = ctx;
- unsigned int i;
+ hmac_key_t ( digest ) *hkey = key;
- /* Construct input pad */
- memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
- if ( key_len <= sizeof ( hctx->pad ) ) {
- memcpy ( hctx->pad, key, key_len );
+ /* Reduce key (if applicable) and zero-pad to block size */
+ memset ( hkey->pad, 0, sizeof ( hkey->pad ) );
+ if ( len <= sizeof ( hkey->pad ) ) {
+ memcpy ( hkey->pad, secret, len );
} else {
digest_init ( digest, hctx->ctx );
- digest_update ( digest, hctx->ctx, key, key_len );
- digest_final ( digest, hctx->ctx, hctx->pad );
+ digest_update ( digest, hctx->ctx, secret, len );
+ digest_final ( digest, hctx->ctx, hkey->pad );
}
- for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
- hctx->pad[i] ^= 0x36;
+}
+
+/**
+ * Initialise HMAC from reduced key
+ *
+ * @v digest Digest algorithm
+ * @v ctx HMAC context
+ * @v hkey HMAC key
+ */
+void hmac_init_key ( struct digest_algorithm *digest, void *ctx,
+ const void *key ) {
+ hmac_context_t ( digest ) *hctx = ctx;
+ const hmac_key_t ( digest ) *hkey = key;
+ unsigned int i;
+
+ /* Construct input pad */
+ for ( i = 0 ; i < sizeof ( hkey->pad ) ; i++ ) {
+ hctx->pad[i] = ( hkey->pad[i] ^ 0x36 );
}
/* Start inner hash */
digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
}
+/**
+ * Initialise HMAC
+ *
+ * @v digest Digest algorithm to use
+ * @v ctx HMAC context
+ * @v secret Secret key
+ * @v len Length of secret key
+ */
+void hmac_init ( struct digest_algorithm *digest, void *ctx,
+ const void *secret, size_t len ) {
+ hmac_context_t ( digest ) *hctx = ctx;
+
+ /* Construct reduced key (in input pad) */
+ hmac_key ( digest, hctx->ctx, secret, len, hctx->pad );
+
+ /* Initialise HMAC */
+ hmac_init_key ( digest, hctx->ctx, hctx->pad );
+}
+
/**
* Finalise HMAC
*
#include <ipxe/crypto.h>
+/** HMAC reduced key type */
+#define hmac_key_t( digest ) struct { \
+ /** HMAC input/output padding */ \
+ uint8_t pad[ digest->blocksize ]; \
+ } __attribute__ (( packed ))
+
/** HMAC context type */
#define hmac_context_t( digest ) struct { \
/** Digest context */ \
uint8_t pad[ digest->blocksize ]; \
} __attribute__ (( packed ))
+/**
+ * Calculate HMAC reduced key size
+ *
+ * @v digest Digest algorithm to use
+ * @ret len HMAC key pad size
+ */
+static inline __attribute__ (( always_inline )) size_t
+hmac_keysize ( struct digest_algorithm *digest ) {
+ hmac_key_t ( digest ) *hkey;
+
+ return sizeof ( hkey->pad );
+}
+
/**
* Calculate HMAC context size
*
digest_update ( digest, hctx->ctx, data, len );
}
+extern void hmac_key ( struct digest_algorithm *digest, void *ctx,
+ const void *secret, size_t len, void *key );
+extern void hmac_init_key ( struct digest_algorithm *digest, void *ctx,
+ const void *key );
extern void hmac_init ( struct digest_algorithm *digest, void *ctx,
- const void *key, size_t key_len );
+ const void *secret, size_t len );
extern void hmac_final ( struct digest_algorithm *digest, void *ctx,
void *hmac );
unsigned int line ) {
struct digest_algorithm *digest = test->digest;
uint8_t ctx[ hmac_ctxsize ( digest ) ];
+ uint8_t key[ hmac_keysize ( digest ) ];
uint8_t hmac[digest->digestsize];
/* Sanity checks */
okx ( sizeof ( ctx ) == ( digest->ctxsize + digest->blocksize ),
file, line );
+ okx ( sizeof ( key ) == digest->blocksize, file, line );
okx ( test->expected_len == digest->digestsize, file, line );
/* Calculate HMAC */
hmac_final ( digest, ctx, hmac );
DBGC ( test, "HMAC-%s result:\n", digest->name );
DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
+ okx ( memcmp ( hmac, test->expected, test->expected_len ) == 0,
+ file, line );
- /* Compare against expected result */
+ /* Calculate HMAC using reduced key */
+ hmac_key ( digest, ctx, test->key, test->key_len, key );
+ DBGC ( test, "HMAC-%s key:\n", digest->name );
+ DBGC_HDA ( test, 0, key, sizeof ( key ) );
+ hmac_init_key ( digest, ctx, key );
+ hmac_update ( digest, ctx, test->data, test->data_len );
+ hmac_final ( digest, ctx, hmac );
+ DBGC ( test, "HMAC-%s result:\n", digest->name );
+ DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
okx ( memcmp ( hmac, test->expected, test->expected_len ) == 0,
file, line );
}