aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-11-09 16:45:54 +0000
committerMichael Brown <mcb30@ipxe.org>2022-11-09 16:48:50 +0000
commit63577207ab95a53b29c1fa441be25ee15747bbe0 (patch)
treeed0b7c1bbc71345cbf40b5b35329caacb8acc5dc
parent7256a6eb24720adfd30c0307a415e51e9a402059 (diff)
downloadipxe-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.c20
-rw-r--r--src/include/ipxe/gcm.h8
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 */