aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-10-28 16:27:10 +0100
committerMichael Brown <mcb30@ipxe.org>2022-11-07 11:19:48 +0000
commit30243ad73957a2e1cc4aedc3f23be66cdf399f00 (patch)
treec0b476b76fed7f2a9c5a3b9ec1ea03f01017a693
parentd1bc872a2e3b682169da4dd708dfe143d539eaaf (diff)
downloadipxe-30243ad73957a2e1cc4aedc3f23be66cdf399f00.zip
ipxe-30243ad73957a2e1cc4aedc3f23be66cdf399f00.tar.gz
ipxe-30243ad73957a2e1cc4aedc3f23be66cdf399f00.tar.bz2
[crypto] Add concept of cipher alignment size
The GCM cipher mode of operation (in common with other counter-based modes of operation) has a notion of blocksize that does not neatly fall into our current abstraction: it does operate in 16-byte blocks but allows for an arbitrary overall data length (i.e. the final block may be incomplete). Model this by adding a concept of alignment size. Each call to encrypt() or decrypt() must begin at a multiple of the alignment size from the start of the data stream. This allows us to model GCM by using a block size of 1 byte and an alignment size of 16 bytes. As a side benefit, this same concept allows us to neatly model the fact that raw AES can encrypt only a single 16-byte block, by specifying an alignment size of zero on this cipher. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/crypto/aes.c1
-rw-r--r--src/crypto/arc4.c1
-rw-r--r--src/crypto/crypto_null.c1
-rw-r--r--src/include/ipxe/cbc.h1
-rw-r--r--src/include/ipxe/crypto.h18
-rw-r--r--src/include/ipxe/ecb.h1
-rw-r--r--src/include/ipxe/gcm.h1
-rw-r--r--src/tests/cipher_test.c10
8 files changed, 33 insertions, 1 deletions
diff --git a/src/crypto/aes.c b/src/crypto/aes.c
index aeeaa1d..5200e77 100644
--- a/src/crypto/aes.c
+++ b/src/crypto/aes.c
@@ -784,6 +784,7 @@ struct cipher_algorithm aes_algorithm = {
.name = "aes",
.ctxsize = sizeof ( struct aes_context ),
.blocksize = AES_BLOCKSIZE,
+ .alignsize = 0,
.authsize = 0,
.setkey = aes_setkey,
.setiv = cipher_null_setiv,
diff --git a/src/crypto/arc4.c b/src/crypto/arc4.c
index 4d98abe..3b6adec 100644
--- a/src/crypto/arc4.c
+++ b/src/crypto/arc4.c
@@ -119,6 +119,7 @@ struct cipher_algorithm arc4_algorithm = {
.name = "ARC4",
.ctxsize = ARC4_CTX_SIZE,
.blocksize = 1,
+ .alignsize = 1,
.authsize = 0,
.setkey = arc4_setkey,
.setiv = cipher_null_setiv,
diff --git a/src/crypto/crypto_null.c b/src/crypto/crypto_null.c
index 26cfbfc..0ad463c 100644
--- a/src/crypto/crypto_null.c
+++ b/src/crypto/crypto_null.c
@@ -84,6 +84,7 @@ struct cipher_algorithm cipher_null = {
.name = "null",
.ctxsize = 0,
.blocksize = 1,
+ .alignsize = 1,
.authsize = 0,
.setkey = cipher_null_setkey,
.setiv = cipher_null_setiv,
diff --git a/src/include/ipxe/cbc.h b/src/include/ipxe/cbc.h
index eead045..382fc90 100644
--- a/src/include/ipxe/cbc.h
+++ b/src/include/ipxe/cbc.h
@@ -95,6 +95,7 @@ struct cipher_algorithm _cbc_cipher = { \
.name = #_cbc_name, \
.ctxsize = sizeof ( struct _cbc_name ## _context ), \
.blocksize = _blocksize, \
+ .alignsize = _blocksize, \
.authsize = 0, \
.setkey = _cbc_name ## _setkey, \
.setiv = _cbc_name ## _setiv, \
diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h
index 842f2f6..ba09c94 100644
--- a/src/include/ipxe/crypto.h
+++ b/src/include/ipxe/crypto.h
@@ -51,8 +51,24 @@ struct cipher_algorithm {
const char *name;
/** Context size */
size_t ctxsize;
- /** Block size */
+ /** Block size
+ *
+ * Every call to encrypt() or decrypt() must be for a multiple
+ * of this size.
+ */
size_t blocksize;
+ /** Alignment size
+ *
+ * Every call to encrypt() or decrypt() must begin at a
+ * multiple of this offset from the start of the stream.
+ * (Equivalently: all but the last call to encrypt() or
+ * decrypt() must be for a multiple of this size.)
+ *
+ * For ciphers supporting additional data, the main data
+ * stream and additional data stream are both considered to
+ * begin at offset zero.
+ */
+ size_t alignsize;
/** Authentication tag size */
size_t authsize;
/** Set key
diff --git a/src/include/ipxe/ecb.h b/src/include/ipxe/ecb.h
index 1d2ebf7..db22d99 100644
--- a/src/include/ipxe/ecb.h
+++ b/src/include/ipxe/ecb.h
@@ -47,6 +47,7 @@ struct cipher_algorithm _ecb_cipher = { \
.name = #_ecb_name, \
.ctxsize = sizeof ( _raw_context ), \
.blocksize = _blocksize, \
+ .alignsize = _blocksize, \
.authsize = 0, \
.setkey = _ecb_name ## _setkey, \
.setiv = _ecb_name ## _setiv, \
diff --git a/src/include/ipxe/gcm.h b/src/include/ipxe/gcm.h
index 6586854..d93eecd 100644
--- a/src/include/ipxe/gcm.h
+++ b/src/include/ipxe/gcm.h
@@ -121,6 +121,7 @@ struct cipher_algorithm _gcm_cipher = { \
.name = #_gcm_name, \
.ctxsize = sizeof ( struct _gcm_name ## _context ), \
.blocksize = 1, \
+ .alignsize = sizeof ( union gcm_block ), \
.authsize = sizeof ( union gcm_block ), \
.setkey = _gcm_name ## _setkey, \
.setiv = _gcm_name ## _setiv, \
diff --git a/src/tests/cipher_test.c b/src/tests/cipher_test.c
index cc732c2..2ead3c8 100644
--- a/src/tests/cipher_test.c
+++ b/src/tests/cipher_test.c
@@ -131,8 +131,18 @@ void cipher_decrypt_okx ( struct cipher_test *test, const char *file,
*/
void cipher_okx ( struct cipher_test *test, const char *file,
unsigned int line ) {
+ struct cipher_algorithm *cipher = test->cipher;
+ size_t len = test->len;
+ /* Sanity checks */
+ okx ( cipher->blocksize != 0, file, line );
+ okx ( ( len % cipher->blocksize ) == 0, file, line );
+ okx ( ( cipher->alignsize % cipher->blocksize ) == 0, file, line );
+
+ /* Report encryption test result */
cipher_encrypt_okx ( test, file, line );
+
+ /* Report decryption test result */
cipher_decrypt_okx ( test, file, line );
}