From 8e478e648fb68ac6f07e4e5cd80a5c1fefcb1cf5 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 24 Oct 2022 16:52:24 +0100 Subject: [crypto] Allow initialisation vector length to vary from cipher blocksize Signed-off-by: Michael Brown --- src/crypto/crypto_null.c | 3 ++- src/include/ipxe/cbc.h | 10 +++++++--- src/include/ipxe/crypto.h | 9 +++++---- src/include/ipxe/ecb.h | 5 +++-- src/net/peerblk.c | 3 ++- src/net/tls.c | 4 ++-- src/tests/cipher_test.c | 6 +++--- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/crypto/crypto_null.c b/src/crypto/crypto_null.c index 9107717..ef6041b 100644 --- a/src/crypto/crypto_null.c +++ b/src/crypto/crypto_null.c @@ -61,7 +61,8 @@ int cipher_null_setkey ( void *ctx __unused, const void *key __unused, return 0; } -void cipher_null_setiv ( void *ctx __unused, const void *iv __unused ) { +void cipher_null_setiv ( void *ctx __unused, const void *iv __unused, + size_t ivlen __unused ) { /* Do nothing */ } diff --git a/src/include/ipxe/cbc.h b/src/include/ipxe/cbc.h index 18a94e1..5c87403 100644 --- a/src/include/ipxe/cbc.h +++ b/src/include/ipxe/cbc.h @@ -33,12 +33,15 @@ static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen, * * @v ctx Context * @v iv Initialisation vector + * @v ivlen Initialisation vector length * @v raw_cipher Underlying cipher algorithm * @v cbc_ctx CBC context */ -static inline void cbc_setiv ( void *ctx __unused, const void *iv, +static inline void cbc_setiv ( void *ctx __unused, + const void *iv, size_t ivlen, struct cipher_algorithm *raw_cipher, void *cbc_ctx ) { + assert ( ivlen == raw_cipher->blocksize ); memcpy ( cbc_ctx, iv, raw_cipher->blocksize ); } @@ -70,9 +73,10 @@ static int _cbc_name ## _setkey ( void *ctx, const void *key, \ return cbc_setkey ( &_cbc_name ## _ctx->raw_ctx, key, keylen, \ &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );\ } \ -static void _cbc_name ## _setiv ( void *ctx, const void *iv ) { \ +static void _cbc_name ## _setiv ( void *ctx, const void *iv, \ + size_t ivlen ) { \ struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \ - cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, \ + cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, ivlen, \ &_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \ } \ static void _cbc_name ## _encrypt ( void *ctx, const void *src, \ diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index 34ab389..931be05 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -64,8 +64,9 @@ struct cipher_algorithm { * * @v ctx Context * @v iv Initialisation vector + * @v ivlen Initialisation vector length */ - void ( * setiv ) ( void *ctx, const void *iv ); + void ( * setiv ) ( void *ctx, const void *iv, size_t ivlen ); /** Encrypt data * * @v ctx Context @@ -190,8 +191,8 @@ static inline int cipher_setkey ( struct cipher_algorithm *cipher, } static inline void cipher_setiv ( struct cipher_algorithm *cipher, - void *ctx, const void *iv ) { - cipher->setiv ( ctx, iv ); + void *ctx, const void *iv, size_t ivlen ) { + cipher->setiv ( ctx, iv, ivlen ); } static inline void cipher_encrypt ( struct cipher_algorithm *cipher, @@ -268,7 +269,7 @@ extern void digest_null_update ( void *ctx, const void *src, size_t len ); extern void digest_null_final ( void *ctx, void *out ); extern int cipher_null_setkey ( void *ctx, const void *key, size_t keylen ); -extern void cipher_null_setiv ( void *ctx, const void *iv ); +extern void cipher_null_setiv ( void *ctx, const void *iv, size_t ivlen ); extern void cipher_null_encrypt ( void *ctx, const void *src, void *dst, size_t len ); extern void cipher_null_decrypt ( void *ctx, const void *src, void *dst, diff --git a/src/include/ipxe/ecb.h b/src/include/ipxe/ecb.h index 4e6aa3c..6c40c61 100644 --- a/src/include/ipxe/ecb.h +++ b/src/include/ipxe/ecb.h @@ -31,8 +31,9 @@ static int _ecb_name ## _setkey ( void *ctx, const void *key, \ size_t keylen ) { \ return cipher_setkey ( &_raw_cipher, ctx, key, keylen ); \ } \ -static void _ecb_name ## _setiv ( void *ctx, const void *iv ) { \ - cipher_setiv ( &_raw_cipher, ctx, iv ); \ +static void _ecb_name ## _setiv ( void *ctx, const void *iv, \ + size_t ivlen ) { \ + cipher_setiv ( &_raw_cipher, ctx, iv, ivlen ); \ } \ static void _ecb_name ## _encrypt ( void *ctx, const void *src, \ void *dst, size_t len ) { \ diff --git a/src/net/peerblk.c b/src/net/peerblk.c index f8994f4..bbd5f16 100644 --- a/src/net/peerblk.c +++ b/src/net/peerblk.c @@ -1033,7 +1033,8 @@ static int peerblk_parse_iv ( struct peerdist_block *peerblk, size_t buf_len, } /* Set initialisation vector */ - cipher_setiv ( peerblk->cipher, peerblk->cipherctx, msg->msg.iv.data ); + cipher_setiv ( peerblk->cipher, peerblk->cipherctx, msg->msg.iv.data, + blksize ); return 0; } diff --git a/src/net/tls.c b/src/net/tls.c index 4aa4d9e..3545f12 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -717,14 +717,14 @@ static int tls_generate_keys ( struct tls_connection *tls ) { /* TX initialisation vector */ cipher_setiv ( tx_cipherspec->suite->cipher, - tx_cipherspec->cipher_ctx, key ); + tx_cipherspec->cipher_ctx, key, iv_size ); DBGC ( tls, "TLS %p TX IV:\n", tls ); DBGC_HD ( tls, key, iv_size ); key += iv_size; /* RX initialisation vector */ cipher_setiv ( rx_cipherspec->suite->cipher, - rx_cipherspec->cipher_ctx, key ); + rx_cipherspec->cipher_ctx, key, iv_size ); DBGC ( tls, "TLS %p RX IV:\n", tls ); DBGC_HD ( tls, key, iv_size ); key += iv_size; diff --git a/src/tests/cipher_test.c b/src/tests/cipher_test.c index 800d6c1..5361502 100644 --- a/src/tests/cipher_test.c +++ b/src/tests/cipher_test.c @@ -61,7 +61,7 @@ void cipher_encrypt_okx ( struct cipher_test *test, const char *file, /* Initialise cipher */ okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0, file, line ); - cipher_setiv ( cipher, ctx, test->iv ); + cipher_setiv ( cipher, ctx, test->iv, test->iv_len ); /* Perform encryption */ cipher_encrypt ( cipher, ctx, test->plaintext, ciphertext, len ); @@ -87,7 +87,7 @@ void cipher_decrypt_okx ( struct cipher_test *test, const char *file, /* Initialise cipher */ okx ( cipher_setkey ( cipher, ctx, test->key, test->key_len ) == 0, file, line ); - cipher_setiv ( cipher, ctx, test->iv ); + cipher_setiv ( cipher, ctx, test->iv, test->iv_len ); /* Perform encryption */ cipher_decrypt ( cipher, ctx, test->ciphertext, plaintext, len ); @@ -143,7 +143,7 @@ cipher_cost ( struct cipher_algorithm *cipher, size_t key_len, /* Initialise cipher */ rc = cipher_setkey ( cipher, ctx, key, key_len ); assert ( rc == 0 ); - cipher_setiv ( cipher, ctx, iv ); + cipher_setiv ( cipher, ctx, iv, sizeof ( iv ) ); /* Profile cipher operation */ memset ( &profiler, 0, sizeof ( profiler ) ); -- cgit v1.1