diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-11-09 16:45:54 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-11-09 16:48:50 +0000 |
commit | 63577207ab95a53b29c1fa441be25ee15747bbe0 (patch) | |
tree | ed0b7c1bbc71345cbf40b5b35329caacb8acc5dc | |
parent | 7256a6eb24720adfd30c0307a415e51e9a402059 (diff) | |
download | ipxe-63577207ab95a53b29c1fa441be25ee15747bbe0.zip ipxe-63577207ab95a53b29c1fa441be25ee15747bbe0.tar.gz ipxe-63577207ab95a53b29c1fa441be25ee15747bbe0.tar.bz2 |
[crypto] Ensure relevant GCM cipher state is cleared by cipher_setiv()
Reset the accumulated authentication state when cipher_setiv() is
called, to allow the cipher to be reused without resetting the key.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/crypto/gcm.c | 20 | ||||
-rw-r--r-- | src/include/ipxe/gcm.h | 8 |
2 files changed, 17 insertions, 11 deletions
diff --git a/src/crypto/gcm.c b/src/crypto/gcm.c index dfccd16..f8d4254 100644 --- a/src/crypto/gcm.c +++ b/src/crypto/gcm.c @@ -452,9 +452,18 @@ int gcm_setkey ( struct gcm_context *context, const void *key, size_t keylen, * @v ivlen Initialisation vector length */ void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) { + union gcm_block *check = ( ( void * ) context ); + + /* Sanity checks */ + linker_assert ( &context->hash == check, gcm_bad_layout ); + linker_assert ( &context->len == check + 1, gcm_bad_layout ); + linker_assert ( &context->ctr == check + 2, gcm_bad_layout ); + linker_assert ( &context->key == check + 3, gcm_bad_layout ); + + /* Reset non-key state */ + memset ( context, 0, offsetof ( typeof ( *context ), key ) ); /* Reset counter */ - memset ( context->ctr.ctr.iv, 0, sizeof ( context->ctr.ctr.iv ) ); context->ctr.ctr.value = cpu_to_be32 ( 1 ); /* Process initialisation vector */ @@ -468,13 +477,10 @@ void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) { /* Calculate hash over initialisation vector */ gcm_process ( context, iv, NULL, iv, ivlen ); gcm_hash ( context, &context->ctr ); - - /* Reset accumulated hash */ - memset ( &context->hash, 0, sizeof ( context->hash ) ); - - /* Reset data lengths */ assert ( context->len.len.add == 0 ); - context->len.len.data = 0; + + /* Reset non-key, non-counter state */ + memset ( context, 0, offsetof ( typeof ( *context ), ctr ) ); } DBGC2 ( context, "GCM %p Y[0]:\n", context ); diff --git a/src/include/ipxe/gcm.h b/src/include/ipxe/gcm.h index d93eecd..90ef0b5 100644 --- a/src/include/ipxe/gcm.h +++ b/src/include/ipxe/gcm.h @@ -44,14 +44,14 @@ union gcm_block { /** GCM context */ struct gcm_context { - /** Hash key (H) */ - union gcm_block key; - /** Counter (Y) */ - union gcm_block ctr; /** Accumulated hash (X) */ union gcm_block hash; /** Accumulated lengths */ union gcm_block len; + /** Counter (Y) */ + union gcm_block ctr; + /** Hash key (H) */ + union gcm_block key; /** Underlying block cipher */ struct cipher_algorithm *raw_cipher; /** Underlying block cipher context */ |