]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Simplify internal HMAC API
authorMichael Brown <mcb30@ipxe.org>
Sun, 9 Oct 2022 14:14:41 +0000 (15:14 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 10 Oct 2022 11:21:54 +0000 (12:21 +0100)
Simplify the internal HMAC API so that the key is provided only at the
point of calling hmac_init(), and the (potentially reduced) key is
stored as part of the context for later use by hmac_final().

This simplifies the calling code, and avoids the need for callers such
as TLS to allocate a potentially variable length block in order to
retain a copy of the unmodified key.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
16 files changed:
src/crypto/hmac.c
src/crypto/hmac_drbg.c
src/crypto/ntlm.c
src/crypto/sha1extra.c
src/include/ipxe/hmac.h
src/include/ipxe/md4.h
src/include/ipxe/md5.h
src/include/ipxe/sha1.h
src/include/ipxe/sha256.h
src/include/ipxe/sha512.h
src/net/80211/wpa_ccmp.c
src/net/80211/wpa_tkip.c
src/net/pccrc.c
src/net/tls.c
src/tests/hmac_test.c
src/tests/pccrc_test.c

index f898619c8825e66a749824536d3b04c121f23279..7109bbf6a83ddc5509b3f603953e437cd5986b81 100644 (file)
@@ -46,94 +46,62 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/crypto.h>
 #include <ipxe/hmac.h>
 
-/**
- * Reduce HMAC key length
- *
- * @v digest           Digest algorithm to use
- * @v digest_ctx       Digest context
- * @v key              Key
- * @v key_len          Length of key
- */
-static void hmac_reduce_key ( struct digest_algorithm *digest,
-                             void *key, size_t *key_len ) {
-       uint8_t digest_ctx[digest->ctxsize];
-
-       digest_init ( digest, digest_ctx );
-       digest_update ( digest, digest_ctx, key, *key_len );
-       digest_final ( digest, digest_ctx, key );
-       *key_len = digest->digestsize;
-}
-
 /**
  * Initialise HMAC
  *
  * @v digest           Digest algorithm to use
- * @v digest_ctx       Digest context
+ * @v ctx              HMAC context
  * @v key              Key
  * @v key_len          Length of key
- *
- * The length of the key should be less than the block size of the
- * digest algorithm being used.  (If the key length is greater, it
- * will be replaced with its own digest, and key_len will be updated
- * accordingly).
  */
-void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
-                void *key, size_t *key_len ) {
-       unsigned char k_ipad[digest->blocksize];
+void hmac_init ( struct digest_algorithm *digest, void *ctx, const void *key,
+                size_t key_len ) {
+       hmac_context_t ( digest ) *hctx = ctx;
        unsigned int i;
 
-       /* Reduce key if necessary */
-       if ( *key_len > sizeof ( k_ipad ) )
-               hmac_reduce_key ( digest, key, key_len );
-
        /* Construct input pad */
-       memset ( k_ipad, 0, sizeof ( k_ipad ) );
-       memcpy ( k_ipad, key, *key_len );
-       for ( i = 0 ; i < sizeof ( k_ipad ) ; i++ ) {
-               k_ipad[i] ^= 0x36;
+       memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
+       if ( key_len <= sizeof ( hctx->pad ) ) {
+               memcpy ( hctx->pad, key, key_len );
+       } else {
+               digest_init ( digest, hctx->ctx );
+               digest_update ( digest, hctx->ctx, key, key_len );
+               digest_final ( digest, hctx->ctx, hctx->pad );
+       }
+       for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
+               hctx->pad[i] ^= 0x36;
        }
-       
+
        /* Start inner hash */
-       digest_init ( digest, digest_ctx );
-       digest_update ( digest, digest_ctx, k_ipad, sizeof ( k_ipad ) );
+       digest_init ( digest, hctx->ctx );
+       digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
 }
 
 /**
  * Finalise HMAC
  *
  * @v digest           Digest algorithm to use
- * @v digest_ctx       Digest context
- * @v key              Key
- * @v key_len          Length of key
+ * @v ctx              HMAC context
  * @v hmac             HMAC digest to fill in
- *
- * The length of the key should be less than the block size of the
- * digest algorithm being used.  (If the key length is greater, it
- * will be replaced with its own digest, and key_len will be updated
- * accordingly).
  */
-void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
-                 void *key, size_t *key_len, void *hmac ) {
-       unsigned char k_opad[digest->blocksize];
+void hmac_final ( struct digest_algorithm *digest, void *ctx, void *hmac ) {
+       hmac_context_t ( digest ) *hctx = ctx;
        unsigned int i;
 
-       /* Reduce key if necessary */
-       if ( *key_len > sizeof ( k_opad ) )
-               hmac_reduce_key ( digest, key, key_len );
-
-       /* Construct output pad */
-       memset ( k_opad, 0, sizeof ( k_opad ) );
-       memcpy ( k_opad, key, *key_len );
-       for ( i = 0 ; i < sizeof ( k_opad ) ; i++ ) {
-               k_opad[i] ^= 0x5c;
+       /* Construct output pad from input pad */
+       for ( i = 0 ; i < sizeof ( hctx->pad ) ; i++ ) {
+               hctx->pad[i] ^= 0x6a;
        }
-       
+
        /* Finish inner hash */
-       digest_final ( digest, digest_ctx, hmac );
+       digest_final ( digest, hctx->ctx, hmac );
 
        /* Perform outer hash */
-       digest_init ( digest, digest_ctx );
-       digest_update ( digest, digest_ctx, k_opad, sizeof ( k_opad ) );
-       digest_update ( digest, digest_ctx, hmac, digest->digestsize );
-       digest_final ( digest, digest_ctx, hmac );
+       digest_init ( digest, hctx->ctx );
+       digest_update ( digest, hctx->ctx, hctx->pad, sizeof ( hctx->pad ) );
+       digest_update ( digest, hctx->ctx, hmac, digest->digestsize );
+       digest_final ( digest, hctx->ctx, hmac );
+
+       /* Erase output pad (from which the key may be derivable) */
+       memset ( hctx->pad, 0, sizeof ( hctx->pad ) );
 }
index 098297716d1763c6bb997f182e3d532ac115ee59..57bde4d1df199c9bacbaf1e376023cf3e8d6b371 100644 (file)
@@ -79,7 +79,7 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
                                   struct hmac_drbg_state *state,
                                   const void *data, size_t len,
                                   const uint8_t single ) {
-       uint8_t context[ hash->ctxsize ];
+       uint8_t context[ hmac_ctxsize ( hash ) ];
        size_t out_len = hash->digestsize;
 
        DBGC ( state, "HMAC_DRBG_%s %p provided data :\n", hash->name, state );
@@ -92,13 +92,11 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
        assert ( ( single == 0x00 ) || ( single == 0x01 ) );
 
        /* K = HMAC ( K, V || single || provided_data ) */
-       hmac_init ( hash, context, state->key, &out_len );
-       assert ( out_len == hash->digestsize );
+       hmac_init ( hash, context, state->key, out_len );
        hmac_update ( hash, context, state->value, out_len );
        hmac_update ( hash, context, &single, sizeof ( single ) );
        hmac_update ( hash, context, data, len );
-       hmac_final ( hash, context, state->key, &out_len, state->key );
-       assert ( out_len == hash->digestsize );
+       hmac_final ( hash, context, state->key );
 
        DBGC ( state, "HMAC_DRBG_%s %p K = HMAC ( K, V || %#02x || "
               "provided_data ) :\n", hash->name, state, single );
@@ -122,7 +120,7 @@ static void hmac_drbg_update_key ( struct digest_algorithm *hash,
  */
 static void hmac_drbg_update_value ( struct digest_algorithm *hash,
                                     struct hmac_drbg_state *state ) {
-       uint8_t context[ hash->ctxsize ];
+       uint8_t context[ hmac_ctxsize ( hash ) ];
        size_t out_len = hash->digestsize;
 
        /* Sanity checks */
@@ -130,11 +128,9 @@ static void hmac_drbg_update_value ( struct digest_algorithm *hash,
        assert ( state != NULL );
 
        /* V = HMAC ( K, V ) */
-       hmac_init ( hash, context, state->key, &out_len );
-       assert ( out_len == hash->digestsize );
+       hmac_init ( hash, context, state->key, out_len );
        hmac_update ( hash, context, state->value, out_len );
-       hmac_final ( hash, context, state->key, &out_len, state->value );
-       assert ( out_len == hash->digestsize );
+       hmac_final ( hash, context, state->value );
 
        DBGC ( state, "HMAC_DRBG_%s %p V = HMAC ( K, V ) :\n",
               hash->name, state );
index 870af2132f58c777d8039c97ec0d5887d943abf1..fb120f8db647abddf13277ac99e2e85e5840d9b5 100644 (file)
@@ -117,10 +117,9 @@ void ntlm_key ( const char *domain, const char *username,
        struct digest_algorithm *md5 = &md5_algorithm;
        union {
                uint8_t md4[MD4_CTX_SIZE];
-               uint8_t md5[MD5_CTX_SIZE];
+               uint8_t md5[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
        } ctx;
        uint8_t digest[MD4_DIGEST_SIZE];
-       size_t digest_len;
        uint8_t c;
        uint16_t wc;
 
@@ -141,8 +140,7 @@ void ntlm_key ( const char *domain, const char *username,
        digest_final ( md4, ctx.md4, digest );
 
        /* Construct HMAC-MD5 of (Unicode) upper-case username */
-       digest_len = sizeof ( digest );
-       hmac_init ( md5, ctx.md5, digest, &digest_len );
+       hmac_init ( md5, ctx.md5, digest, sizeof ( digest ) );
        while ( ( c = *(username++) ) ) {
                wc = cpu_to_le16 ( toupper ( c ) );
                hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
@@ -151,7 +149,7 @@ void ntlm_key ( const char *domain, const char *username,
                wc = cpu_to_le16 ( c );
                hmac_update ( md5, ctx.md5, &wc, sizeof ( wc ) );
        }
-       hmac_final ( md5, ctx.md5, digest, &digest_len, key->raw );
+       hmac_final ( md5, ctx.md5, key->raw );
        DBGC ( key, "NTLM key:\n" );
        DBGC_HDA ( key, 0, key, sizeof ( *key ) );
 }
@@ -170,8 +168,7 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
                     struct ntlm_nt_response *nt ) {
        struct digest_algorithm *md5 = &md5_algorithm;
        struct ntlm_nonce tmp_nonce;
-       uint8_t ctx[MD5_CTX_SIZE];
-       size_t key_len = sizeof ( *key );
+       uint8_t ctx[ MD5_CTX_SIZE + MD5_BLOCK_SIZE ];
        unsigned int i;
 
        /* Generate random nonce, if needed */
@@ -183,10 +180,10 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
 
        /* Construct LAN Manager response */
        memcpy ( &lm->nonce, nonce, sizeof ( lm->nonce ) );
-       hmac_init ( md5, ctx, key->raw, &key_len );
+       hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
        hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
        hmac_update ( md5, ctx, &lm->nonce, sizeof ( lm->nonce ) );
-       hmac_final ( md5, ctx, key->raw, &key_len, lm->digest );
+       hmac_final ( md5, ctx, lm->digest );
        DBGC ( key, "NTLM LAN Manager response:\n" );
        DBGC_HDA ( key, 0, lm, sizeof ( *lm ) );
 
@@ -195,14 +192,14 @@ void ntlm_response ( struct ntlm_challenge_info *info, struct ntlm_key *key,
        nt->version = NTLM_VERSION_NTLMV2;
        nt->high = NTLM_VERSION_NTLMV2;
        memcpy ( &nt->nonce, nonce, sizeof ( nt->nonce ) );
-       hmac_init ( md5, ctx, key->raw, &key_len );
+       hmac_init ( md5, ctx, key->raw, sizeof ( *key ) );
        hmac_update ( md5, ctx, info->nonce, sizeof ( *info->nonce ) );
        hmac_update ( md5, ctx, &nt->version,
                      ( sizeof ( *nt ) -
                        offsetof ( typeof ( *nt ), version ) ) );
        hmac_update ( md5, ctx, info->target, info->len );
        hmac_update ( md5, ctx, &nt->zero, sizeof ( nt->zero ) );
-       hmac_final ( md5, ctx, key->raw, &key_len, nt->digest );
+       hmac_final ( md5, ctx, nt->digest );
        DBGC ( key, "NTLM NT response prefix:\n" );
        DBGC_HDA ( key, 0, nt, sizeof ( *nt ) );
 }
index cec0d35e5bf4251c0b56d3b604cfa571e20581c8..9e296eb2ccab7159f3572e737e95d513fe2f7670 100644 (file)
@@ -49,7 +49,7 @@ void prf_sha1 ( const void *key, size_t key_len, const char *label,
        u8 in[strlen ( label ) + 1 + data_len + 1]; /* message to HMAC */
        u8 *in_blknr;           /* pointer to last byte of in, block number */
        u8 out[SHA1_DIGEST_SIZE]; /* HMAC-SHA1 result */
-       u8 sha1_ctx[SHA1_CTX_SIZE]; /* SHA1 context */
+       u8 ctx[SHA1_CTX_SIZE + SHA1_BLOCK_SIZE]; /* HMAC-SHA1 context */
        const size_t label_len = strlen ( label );
 
        /* The HMAC-SHA-1 is calculated using the given key on the
@@ -65,9 +65,9 @@ void prf_sha1 ( const void *key, size_t key_len, const char *label,
        for ( blk = 0 ;; blk++ ) {
                *in_blknr = blk;
 
-               hmac_init ( &sha1_algorithm, sha1_ctx, keym, &key_len );
-               hmac_update ( &sha1_algorithm, sha1_ctx, in, sizeof ( in ) );
-               hmac_final ( &sha1_algorithm, sha1_ctx, keym, &key_len, out );
+               hmac_init ( &sha1_algorithm, ctx, keym, key_len );
+               hmac_update ( &sha1_algorithm, ctx, in, sizeof ( in ) );
+               hmac_final ( &sha1_algorithm, ctx, out );
 
                if ( prf_len <= sizeof ( out ) ) {
                        memcpy ( prf, out, prf_len );
@@ -100,7 +100,7 @@ static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
        u8 pass[pass_len];      /* modifiable passphrase */
        u8 in[salt_len + 4];    /* input buffer to first round */
        u8 last[SHA1_DIGEST_SIZE]; /* output of round N, input of N+1 */
-       u8 sha1_ctx[SHA1_CTX_SIZE];
+       u8 ctx[SHA1_CTX_SIZE + SHA1_BLOCK_SIZE];
        u8 *next_in = in;       /* changed to `last' after first round */
        int next_size = sizeof ( in );
        int i;
@@ -114,9 +114,9 @@ static void pbkdf2_sha1_f ( const void *passphrase, size_t pass_len,
        memset ( block, 0, sizeof ( last ) );
 
        for ( i = 0; i < iterations; i++ ) {
-               hmac_init ( &sha1_algorithm, sha1_ctx, pass, &pass_len );
-               hmac_update ( &sha1_algorithm, sha1_ctx, next_in, next_size );
-               hmac_final ( &sha1_algorithm, sha1_ctx, pass, &pass_len, last );
+               hmac_init ( &sha1_algorithm, ctx, pass, pass_len );
+               hmac_update ( &sha1_algorithm, ctx, next_in, next_size );
+               hmac_final ( &sha1_algorithm, ctx, last );
 
                for ( j = 0; j < sizeof ( last ); j++ ) {
                        block[j] ^= last[j];
index 09d3e273ded1589723ae322631137853fe805ab4..cf9d086777fdecac2c6bfab53d054a97ad7f27dc 100644 (file)
@@ -10,23 +10,45 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <ipxe/crypto.h>
 
+/** HMAC context type */
+#define hmac_context_t( digest ) struct {                              \
+               /** Digest context */                                   \
+               uint8_t ctx[ digest->ctxsize ];                         \
+               /** HMAC input/output padding */                        \
+               uint8_t pad[ digest->blocksize ];                       \
+       } __attribute__ (( packed ))
+
+/**
+ * Calculate HMAC context size
+ *
+ * @v digest           Digest algorithm to use
+ * @ret len            HMAC context size
+ */
+static inline __attribute__ (( always_inline )) size_t
+hmac_ctxsize ( struct digest_algorithm *digest ) {
+       hmac_context_t ( digest ) *hctx;
+
+       return sizeof ( *hctx );
+}
+
 /**
  * Update HMAC
  *
  * @v digest           Digest algorithm to use
- * @v digest_ctx       Digest context
+ * @v ctx              HMAC context
  * @v data             Data
  * @v len              Length of data
  */
-static inline void hmac_update ( struct digest_algorithm *digest,
-                                void *digest_ctx, const void *data,
-                                size_t len ) {
-       digest_update ( digest, digest_ctx, data, len );
+static inline void hmac_update ( struct digest_algorithm *digest, void *ctx,
+                                const void *data, size_t len ) {
+       hmac_context_t ( digest ) *hctx = ctx;
+
+       digest_update ( digest, hctx->ctx, data, len );
 }
 
-extern void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
-                       void *key, size_t *key_len );
-extern void hmac_final ( struct digest_algorithm *digest, void *digest_ctx,
-                        void *key, size_t *key_len, void *hmac );
+extern void hmac_init ( struct digest_algorithm *digest, void *ctx,
+                       const void *key, size_t key_len );
+extern void hmac_final ( struct digest_algorithm *digest, void *ctx,
+                        void *hmac );
 
 #endif /* _IPXE_HMAC_H */
index 8f172e62677792b9b6119cd877209d5df5af7e1e..9f6cb8a5f050b1517c0b91b7a9aaaa1a1d021424 100644 (file)
@@ -65,6 +65,9 @@ struct md4_context {
 /** MD4 context size */
 #define MD4_CTX_SIZE sizeof ( struct md4_context )
 
+/** MD4 block size */
+#define MD4_BLOCK_SIZE sizeof ( union md4_block )
+
 /** MD4 digest size */
 #define MD4_DIGEST_SIZE sizeof ( struct md4_digest )
 
index 05c3974c8d48ec43a70b1afb46f747910ceb8be2..527ad3658c1247a68dce363992901ec305803944 100644 (file)
@@ -65,6 +65,9 @@ struct md5_context {
 /** MD5 context size */
 #define MD5_CTX_SIZE sizeof ( struct md5_context )
 
+/** MD5 block size */
+#define MD5_BLOCK_SIZE sizeof ( union md5_block )
+
 /** MD5 digest size */
 #define MD5_DIGEST_SIZE sizeof ( struct md5_digest )
 
index a97035ec769a5842ceadfd4f62558e8e2f061be5..9cbbebdee356494681225b9b3c413d5014a95bff 100644 (file)
@@ -65,6 +65,9 @@ struct sha1_context {
 /** SHA-1 context size */
 #define SHA1_CTX_SIZE sizeof ( struct sha1_context )
 
+/** SHA-1 block size */
+#define SHA1_BLOCK_SIZE sizeof ( union sha1_block )
+
 /** SHA-1 digest size */
 #define SHA1_DIGEST_SIZE sizeof ( struct sha1_digest )
 
index e234cce3370ad102d36a2bc9b7b152a9da0c53f9..f226ad07b3917bba4d755e0857a2db61415049ce 100644 (file)
@@ -70,6 +70,9 @@ struct sha256_context {
 /** SHA-256 context size */
 #define SHA256_CTX_SIZE sizeof ( struct sha256_context )
 
+/** SHA-256 block size */
+#define SHA256_BLOCK_SIZE sizeof ( union sha256_block )
+
 /** SHA-256 digest size */
 #define SHA256_DIGEST_SIZE sizeof ( struct sha256_digest )
 
index 8e22d8357b72455cb190052125581ca125b32105..82a9e4e69d9333850c72167d8d0b926d48add5bd 100644 (file)
@@ -72,6 +72,9 @@ struct sha512_context {
 /** SHA-512 context size */
 #define SHA512_CTX_SIZE sizeof ( struct sha512_context )
 
+/** SHA-512 block size */
+#define SHA512_BLOCK_SIZE sizeof ( union sha512_block )
+
 /** SHA-512 digest size */
 #define SHA512_DIGEST_SIZE sizeof ( struct sha512_digest )
 
index a073c6a3cfec681a44198df14ba338e4e1673c99..0abd217e79d92d8854a1f7a45264fe02a095a368 100644 (file)
@@ -478,16 +478,15 @@ struct net80211_crypto ccmp_crypto __net80211_crypto = {
 static void ccmp_kie_mic ( const void *kck, const void *msg, size_t len,
                           void *mic )
 {
-       u8 sha1_ctx[SHA1_CTX_SIZE];
+       u8 ctx[SHA1_CTX_SIZE + SHA1_BLOCK_SIZE];
        u8 kckb[16];
        u8 hash[SHA1_DIGEST_SIZE];
-       size_t kck_len = 16;
 
-       memcpy ( kckb, kck, kck_len );
+       memcpy ( kckb, kck, sizeof ( kckb ) );
 
-       hmac_init ( &sha1_algorithm, sha1_ctx, kckb, &kck_len );
-       hmac_update ( &sha1_algorithm, sha1_ctx, msg, len );
-       hmac_final ( &sha1_algorithm, sha1_ctx, kckb, &kck_len, hash );
+       hmac_init ( &sha1_algorithm, ctx, kckb, sizeof ( kckb ) );
+       hmac_update ( &sha1_algorithm, ctx, msg, len );
+       hmac_final ( &sha1_algorithm, ctx, hash );
 
        memcpy ( mic, hash, 16 );
 }
index 3b1934b59ec0d19e60af36a63e85cdc253d065af..3bd651512d939c622ab49b30afe85ed69044243b 100644 (file)
@@ -545,15 +545,14 @@ struct net80211_crypto tkip_crypto __net80211_crypto = {
 static void tkip_kie_mic ( const void *kck, const void *msg, size_t len,
                           void *mic )
 {
-       uint8_t ctx[MD5_CTX_SIZE];
+       uint8_t ctx[MD5_CTX_SIZE + MD5_BLOCK_SIZE];
        u8 kckb[16];
-       size_t kck_len = 16;
 
-       memcpy ( kckb, kck, kck_len );
+       memcpy ( kckb, kck, sizeof ( kckb ) );
 
-       hmac_init ( &md5_algorithm, ctx, kckb, &kck_len );
+       hmac_init ( &md5_algorithm, ctx, kckb, sizeof ( kckb ) );
        hmac_update ( &md5_algorithm, ctx, msg, len );
-       hmac_final ( &md5_algorithm, ctx, kckb, &kck_len, mic );
+       hmac_final ( &md5_algorithm, ctx, mic );
 }
 
 /**
index 4cd82cd1c7497ca19ee3be71971b20e4f5b61a28..a94bc0e1197b21212ade8216badc6edcca5b7025 100644 (file)
@@ -104,9 +104,8 @@ static void peerdist_info_segment_hash ( struct peerdist_info_segment *segment,
                                         const void *hash, const void *secret ){
        const struct peerdist_info *info = segment->info;
        struct digest_algorithm *digest = info->digest;
-       uint8_t ctx[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
        size_t digestsize = info->digestsize;
-       size_t secretsize = digestsize;
        static const uint16_t magic[] = PEERDIST_SEGMENT_ID_MAGIC;
 
        /* Sanity check */
@@ -121,12 +120,10 @@ static void peerdist_info_segment_hash ( struct peerdist_info_segment *segment,
        memcpy ( segment->secret, secret, digestsize );
 
        /* Calculate segment identifier */
-       hmac_init ( digest, ctx, segment->secret, &secretsize );
-       assert ( secretsize == digestsize );
+       hmac_init ( digest, ctx, segment->secret, digestsize );
        hmac_update ( digest, ctx, segment->hash, digestsize );
        hmac_update ( digest, ctx, magic, sizeof ( magic ) );
-       hmac_final ( digest, ctx, segment->secret, &secretsize, segment->id );
-       assert ( secretsize == digestsize );
+       hmac_final ( digest, ctx, segment->id );
 }
 
 /******************************************************************************
index 3c414445086e8a985ed9667c9dea1c7463fd44f6..21f7073400956f92255daaef2bf6117e79a8013b 100644 (file)
@@ -458,17 +458,17 @@ static int tls_generate_random ( struct tls_connection *tls,
  * Update HMAC with a list of ( data, len ) pairs
  *
  * @v digest           Hash function to use
- * @v digest_ctx       Digest context
+ * @v ctx              HMAC context
  * @v args             ( data, len ) pairs of data, terminated by NULL
  */
 static void tls_hmac_update_va ( struct digest_algorithm *digest,
-                                void *digest_ctx, va_list args ) {
+                                void *ctx, va_list args ) {
        void *data;
        size_t len;
 
        while ( ( data = va_arg ( args, void * ) ) ) {
                len = va_arg ( args, size_t );
-               hmac_update ( digest, digest_ctx, data, len );
+               hmac_update ( digest, ctx, data, len );
        }
 }
 
@@ -485,43 +485,38 @@ static void tls_hmac_update_va ( struct digest_algorithm *digest,
  */
 static void tls_p_hash_va ( struct tls_connection *tls,
                            struct digest_algorithm *digest,
-                           void *secret, size_t secret_len,
+                           const void *secret, size_t secret_len,
                            void *out, size_t out_len,
                            va_list seeds ) {
-       uint8_t secret_copy[secret_len];
-       uint8_t digest_ctx[digest->ctxsize];
-       uint8_t digest_ctx_partial[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
+       uint8_t ctx_partial[ sizeof ( ctx ) ];
        uint8_t a[digest->digestsize];
        uint8_t out_tmp[digest->digestsize];
        size_t frag_len = digest->digestsize;
        va_list tmp;
 
-       /* Copy the secret, in case HMAC modifies it */
-       memcpy ( secret_copy, secret, secret_len );
-       secret = secret_copy;
        DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
        DBGC2_HD ( tls, secret, secret_len );
 
        /* Calculate A(1) */
-       hmac_init ( digest, digest_ctx, secret, &secret_len );
+       hmac_init ( digest, ctx, secret, secret_len );
        va_copy ( tmp, seeds );
-       tls_hmac_update_va ( digest, digest_ctx, tmp );
+       tls_hmac_update_va ( digest, ctx, tmp );
        va_end ( tmp );
-       hmac_final ( digest, digest_ctx, secret, &secret_len, a );
+       hmac_final ( digest, ctx, a );
        DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
        DBGC2_HD ( tls, &a, sizeof ( a ) );
 
        /* Generate as much data as required */
        while ( out_len ) {
                /* Calculate output portion */
-               hmac_init ( digest, digest_ctx, secret, &secret_len );
-               hmac_update ( digest, digest_ctx, a, sizeof ( a ) );
-               memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize );
+               hmac_init ( digest, ctx, secret, secret_len );
+               hmac_update ( digest, ctx, a, sizeof ( a ) );
+               memcpy ( ctx_partial, ctx, sizeof ( ctx_partial ) );
                va_copy ( tmp, seeds );
-               tls_hmac_update_va ( digest, digest_ctx, tmp );
+               tls_hmac_update_va ( digest, ctx, tmp );
                va_end ( tmp );
-               hmac_final ( digest, digest_ctx,
-                            secret, &secret_len, out_tmp );
+               hmac_final ( digest, ctx, out_tmp );
 
                /* Copy output */
                if ( frag_len > out_len )
@@ -531,8 +526,7 @@ static void tls_p_hash_va ( struct tls_connection *tls,
                DBGC2_HD ( tls, out, frag_len );
 
                /* Calculate A(i) */
-               hmac_final ( digest, digest_ctx_partial,
-                            secret, &secret_len, a );
+               hmac_final ( digest, ctx_partial, a );
                DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
                DBGC2_HD ( tls, &a, sizeof ( a ) );
 
@@ -551,13 +545,13 @@ static void tls_p_hash_va ( struct tls_connection *tls,
  * @v out_len          Length of output buffer
  * @v ...              ( data, len ) pairs of seed data, terminated by NULL
  */
-static void tls_prf ( struct tls_connection *tls, void *secret,
+static void tls_prf ( struct tls_connection *tls, const void *secret,
                      size_t secret_len, void *out, size_t out_len, ... ) {
        va_list seeds;
        va_list tmp;
        size_t subsecret_len;
-       void *md5_secret;
-       void *sha1_secret;
+       const void *md5_secret;
+       const void *sha1_secret;
        uint8_t buf[out_len];
        unsigned int i;
 
@@ -2213,7 +2207,7 @@ static void tls_hmac_init ( struct tls_cipherspec *cipherspec, void *ctx,
                            uint64_t seq, struct tls_header *tlshdr ) {
        struct digest_algorithm *digest = cipherspec->suite->digest;
 
-       hmac_init ( digest, ctx, cipherspec->mac_secret, &digest->digestsize );
+       hmac_init ( digest, ctx, cipherspec->mac_secret, digest->digestsize );
        seq = cpu_to_be64 ( seq );
        hmac_update ( digest, ctx, &seq, sizeof ( seq ) );
        hmac_update ( digest, ctx, tlshdr, sizeof ( *tlshdr ) );
@@ -2245,8 +2239,7 @@ static void tls_hmac_final ( struct tls_cipherspec *cipherspec, void *ctx,
                             void *hmac ) {
        struct digest_algorithm *digest = cipherspec->suite->digest;
 
-       hmac_final ( digest, ctx, cipherspec->mac_secret,
-                    &digest->digestsize, hmac );
+       hmac_final ( digest, ctx, hmac );
 }
 
 /**
@@ -2263,7 +2256,7 @@ static void tls_hmac ( struct tls_cipherspec *cipherspec,
                       uint64_t seq, struct tls_header *tlshdr,
                       const void *data, size_t len, void *hmac ) {
        struct digest_algorithm *digest = cipherspec->suite->digest;
-       uint8_t ctx[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
 
        tls_hmac_init ( cipherspec, ctx, seq, tlshdr );
        tls_hmac_update ( cipherspec, ctx, data, len );
@@ -2545,7 +2538,7 @@ static int tls_new_ciphertext ( struct tls_connection *tls,
        struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
        struct cipher_algorithm *cipher = cipherspec->suite->cipher;
        struct digest_algorithm *digest = cipherspec->suite->digest;
-       uint8_t ctx[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
        uint8_t verify_mac[digest->digestsize];
        struct io_buffer *iobuf;
        void *mac;
index 871926f90e24b1959d830c6b70899f409590f88b..5267999e420ee3347fce0b9fc687e72415ebcc3c 100644 (file)
@@ -100,26 +100,22 @@ struct hmac_test {
 static void hmac_okx ( struct hmac_test *test, const char *file,
                       unsigned int line ) {
        struct digest_algorithm *digest = test->digest;
-       uint8_t ctx[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
        uint8_t hmac[digest->digestsize];
-       uint8_t key[test->key_len];
-       size_t key_len;
 
        /* Sanity checks */
+       okx ( sizeof ( ctx ) == ( digest->ctxsize + digest->blocksize ),
+             file, line );
        okx ( test->expected_len == digest->digestsize, file, line );
 
-       /* Create modifiable copy of key */
-       memcpy ( key, test->key, test->key_len );
-       key_len = test->key_len;
-
        /* Calculate HMAC */
        DBGC ( test, "HMAC-%s key:\n", digest->name );
        DBGC_HDA ( test, 0, test->key, test->key_len );
        DBGC ( test, "HMAC-%s data:\n", digest->name );
        DBGC_HDA ( test, 0, test->data, test->data_len );
-       hmac_init ( digest, ctx, key, &key_len );
+       hmac_init ( digest, ctx, test->key, test->key_len );
        hmac_update ( digest, ctx, test->data, test->data_len );
-       hmac_final ( digest, ctx, key, &key_len, hmac );
+       hmac_final ( digest, ctx, hmac );
        DBGC ( test, "HMAC-%s result:\n", digest->name );
        DBGC_HDA ( test, 0, hmac, sizeof ( hmac ) );
 
index f4ab573acbed0dcceecc13b3448ce12f0588aa7b..e69493202417cdf3d01b5e7d40f7f67de0dc02e9 100644 (file)
@@ -467,11 +467,10 @@ peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
                               uint8_t *pass, size_t pass_len,
                               const char *file, unsigned int line ) {
        struct digest_algorithm *digest = info->digest;
-       uint8_t ctx[digest->ctxsize];
+       uint8_t ctx[ hmac_ctxsize ( digest ) ];
        uint8_t secret[digest->digestsize];
        uint8_t expected[digest->digestsize];
        size_t digestsize = info->digestsize;
-       size_t secretsize = digestsize;
 
        /* Calculate server secret */
        digest_init ( digest, ctx );
@@ -479,11 +478,9 @@ peerdist_info_passphrase_okx ( struct peerdist_info_segment_test *test,
        digest_final ( digest, ctx, secret );
 
        /* Calculate expected segment secret */
-       hmac_init ( digest, ctx, secret, &secretsize );
-       assert ( secretsize == digestsize );
+       hmac_init ( digest, ctx, secret, digestsize );
        hmac_update ( digest, ctx, test->expected_hash, digestsize );
-       hmac_final ( digest, ctx, secret, &secretsize, expected );
-       assert ( secretsize == digestsize );
+       hmac_final ( digest, ctx, expected );
 
        /* Verify segment secret */
        okx ( memcmp ( test->expected_secret, expected, digestsize ) == 0,