]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Use private data field for cipher algorithms master
authorMichael Brown <mcb30@ipxe.org>
Fri, 19 Jun 2026 12:26:00 +0000 (13:26 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 19 Jun 2026 12:26:00 +0000 (13:26 +0100)
Following the example of commit 25072c1 ("[crypto] Use private data
field for key exchange algorithms"), extend the definition of a cipher
algorithm to include an opaque private data field, and use this to
eliminate the wrapper functions generated for the various block cipher
modes of operation by ECB_CIPHER(), CBC_CIPHER(), and GCM_CIPHER().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/aes.c
src/crypto/arc4.c
src/crypto/cbc.c
src/crypto/crypto_null.c
src/crypto/des.c
src/crypto/ecb.c
src/crypto/gcm.c
src/include/ipxe/cbc.h
src/include/ipxe/crypto.h
src/include/ipxe/ecb.h
src/include/ipxe/gcm.h

index fe6ccb2229cd33b936d80690c07cc81ef6be43c7..c9836147426234f42ffab806457ead1c86ebeedc 100644 (file)
@@ -391,12 +391,14 @@ static void aes_final ( const struct aes_table *table, size_t stride,
 /**
  * Encrypt data
  *
 /**
  * Encrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  */
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  */
-static void aes_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
+static void aes_encrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
+                         const void *src, void *dst, size_t len ) {
        struct aes_context *aes = ctx;
        union aes_matrix buffer[2];
        union aes_matrix *in = &buffer[0];
        struct aes_context *aes = ctx;
        union aes_matrix buffer[2];
        union aes_matrix *in = &buffer[0];
@@ -427,12 +429,14 @@ static void aes_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
 /**
  * Decrypt data
  *
 /**
  * Decrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  */
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  */
-static void aes_decrypt ( void *ctx, const void *src, void *dst, size_t len ) {
+static void aes_decrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
+                         const void *src, void *dst, size_t len ) {
        struct aes_context *aes = ctx;
        union aes_matrix buffer[2];
        union aes_matrix *in = &buffer[0];
        struct aes_context *aes = ctx;
        union aes_matrix buffer[2];
        union aes_matrix *in = &buffer[0];
@@ -674,12 +678,14 @@ aes_key_rcon ( uint32_t column, unsigned int rcon ) {
 /**
  * Set key
  *
 /**
  * Set key
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v key              Key
  * @v keylen           Key length
  * @ret rc             Return status code
  */
  * @v ctx              Context
  * @v key              Key
  * @v keylen           Key length
  * @ret rc             Return status code
  */
-static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
+static int aes_setkey ( struct cipher_algorithm *cipher __unused, void *ctx,
+                       const void *key, size_t keylen ) {
        struct aes_context *aes = ctx;
        union aes_matrix *enc;
        union aes_matrix *dec;
        struct aes_context *aes = ctx;
        union aes_matrix *enc;
        union aes_matrix *dec;
index 3b6adec199b3ab56bb61dc5a4c4cce789732d7f2..2866688eb8d10e1551b379c6c284657688ed34ae 100644 (file)
@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 /**
  * Set ARC4 key
  *
 /**
  * Set ARC4 key
  *
+ * @v cipher   Cipher algorithm
  * @v ctxv     ARC4 encryption context
  * @v keyv     Key to set
  * @v keylen   Length of key
  * @v ctxv     ARC4 encryption context
  * @v keyv     Key to set
  * @v keylen   Length of key
@@ -39,7 +40,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
  * there is no standard length for an initialisation vector in the
  * cipher.
  */
  * there is no standard length for an initialisation vector in the
  * cipher.
  */
-static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen )
+static int arc4_setkey ( struct cipher_algorithm *cipher __unused, void *ctxv,
+                        const void *keyv, size_t keylen )
 {
        struct arc4_ctx *ctx = ctxv;
        const u8 *key = keyv;
 {
        struct arc4_ctx *ctx = ctxv;
        const u8 *key = keyv;
@@ -62,6 +64,7 @@ static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen )
 /**
  * Perform ARC4 encryption or decryption
  *
 /**
  * Perform ARC4 encryption or decryption
  *
+ * @v cipher   Cipher algorithm
  * @v ctxv     ARC4 encryption context
  * @v srcv     Data to encrypt or decrypt
  * @v dstv     Location to store encrypted or decrypted data
  * @v ctxv     ARC4 encryption context
  * @v srcv     Data to encrypt or decrypt
  * @v dstv     Location to store encrypted or decrypted data
@@ -75,8 +78,8 @@ static int arc4_setkey ( void *ctxv, const void *keyv, size_t keylen )
  * If you pass a @c NULL source or destination pointer, @a len
  * keystream bytes will be consumed without encrypting any data.
  */
  * If you pass a @c NULL source or destination pointer, @a len
  * keystream bytes will be consumed without encrypting any data.
  */
-static void arc4_xor ( void *ctxv, const void *srcv, void *dstv,
-                      size_t len )
+static void arc4_xor ( struct cipher_algorithm *cipher __unused, void *ctxv,
+                      const void *srcv, void *dstv, size_t len )
 {
        struct arc4_ctx *ctx = ctxv;
        const u8 *src = srcv;
 {
        struct arc4_ctx *ctx = ctxv;
        const u8 *src = srcv;
@@ -109,10 +112,12 @@ static void arc4_xor ( void *ctxv, const void *srcv, void *dstv,
 void arc4_skip ( const void *key, size_t keylen, size_t skip,
                 const void *src, void *dst, size_t msglen )
 {
 void arc4_skip ( const void *key, size_t keylen, size_t skip,
                 const void *src, void *dst, size_t msglen )
 {
+       struct cipher_algorithm *cipher = &arc4_algorithm;
        struct arc4_ctx ctx;
        struct arc4_ctx ctx;
-       arc4_setkey ( &ctx, key, keylen );
-       arc4_xor ( &ctx, NULL, NULL, skip );
-       arc4_xor ( &ctx, src, dst, msglen );
+
+       arc4_setkey ( cipher, &ctx, key, keylen );
+       arc4_xor ( cipher, &ctx, NULL, NULL, skip );
+       arc4_xor ( cipher, &ctx, src, dst, msglen );
 }
 
 struct cipher_algorithm arc4_algorithm = {
 }
 
 struct cipher_algorithm arc4_algorithm = {
index ddba7abd9ce4d87868631831fe4cfa4ae0178b06..ff45dd9e8f777d50f35ba2d388f3b322e019df50 100644 (file)
@@ -35,6 +35,43 @@ FILE_SECBOOT ( PERMITTED );
  *
  */
 
  *
  */
 
+/**
+ * Set key
+ *
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
+ * @v key              Key
+ * @v keylen           Key length
+ * @ret rc             Return status code
+ */
+int cbc_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                const void *key, size_t keylen ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       size_t blocksize = cipher->blocksize;
+       size_t ctxsize = cipher->ctxsize;
+       cbc_context_t ( blocksize, ctxsize ) *context = ctx;
+
+       return cipher_setkey ( raw_cipher, context->raw, key, keylen );
+}
+
+/**
+ * Set initialisation vector
+ *
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
+ * @v iv               Initialisation vector
+ * @v ivlen            Initialisation vector length
+ */
+void cbc_setiv ( struct cipher_algorithm *cipher, void *ctx,
+                const void *iv, size_t ivlen ) {
+       size_t blocksize = cipher->blocksize;
+       size_t ctxsize = cipher->ctxsize;
+       cbc_context_t ( blocksize, ctxsize ) *context = ctx;
+
+       assert ( ivlen == sizeof ( context->cbc ) );
+       memcpy ( context->cbc, iv, sizeof ( context->cbc ) );
+}
+
 /**
  * XOR data blocks
  *
 /**
  * XOR data blocks
  *
@@ -57,23 +94,26 @@ static void cbc_xor ( const void *src, void *dst, size_t len ) {
 /**
  * Encrypt data
  *
 /**
  * Encrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
- * @v raw_cipher       Underlying cipher algorithm
- * @v cbc_ctx          CBC context
  */
  */
-void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len,
-                  struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
-       size_t blocksize = raw_cipher->blocksize;
+void cbc_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       size_t blocksize = cipher->blocksize;
+       size_t ctxsize = cipher->ctxsize;
+       cbc_context_t ( blocksize, ctxsize ) *context = ctx;
 
        assert ( ( len % blocksize ) == 0 );
 
        while ( len ) {
 
        assert ( ( len % blocksize ) == 0 );
 
        while ( len ) {
-               cbc_xor ( src, cbc_ctx, blocksize );
-               cipher_encrypt ( raw_cipher, ctx, cbc_ctx, dst, blocksize );
-               memcpy ( cbc_ctx, dst, blocksize );
+               cbc_xor ( src, context->cbc, blocksize );
+               cipher_encrypt ( raw_cipher, context->raw, context->cbc, dst,
+                                blocksize );
+               memcpy ( context->cbc, dst, blocksize );
                dst += blocksize;
                src += blocksize;
                len -= blocksize;
                dst += blocksize;
                src += blocksize;
                len -= blocksize;
@@ -83,25 +123,28 @@ void cbc_encrypt ( void *ctx, const void *src, void *dst, size_t len,
 /**
  * Decrypt data
  *
 /**
  * Decrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
- * @v raw_cipher       Underlying cipher algorithm
- * @v cbc_ctx          CBC context
  */
  */
-void cbc_decrypt ( void *ctx, const void *src, void *dst, size_t len,
-                  struct cipher_algorithm *raw_cipher, void *cbc_ctx ) {
-       size_t blocksize = raw_cipher->blocksize;
+void cbc_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       size_t blocksize = cipher->blocksize;
+       size_t ctxsize = cipher->ctxsize;
+       cbc_context_t ( blocksize, ctxsize ) *context = ctx;
        uint8_t next_cbc_ctx[blocksize];
 
        assert ( ( len % blocksize ) == 0 );
 
        while ( len ) {
                memcpy ( next_cbc_ctx, src, blocksize );
        uint8_t next_cbc_ctx[blocksize];
 
        assert ( ( len % blocksize ) == 0 );
 
        while ( len ) {
                memcpy ( next_cbc_ctx, src, blocksize );
-               cipher_decrypt ( raw_cipher, ctx, src, dst, blocksize );
-               cbc_xor ( cbc_ctx, dst, blocksize );
-               memcpy ( cbc_ctx, next_cbc_ctx, blocksize );
+               cipher_decrypt ( raw_cipher, context->raw, src, dst,
+                                blocksize );
+               cbc_xor ( context->cbc, dst, blocksize );
+               memcpy ( context->cbc, next_cbc_ctx, blocksize );
                dst += blocksize;
                src += blocksize;
                len -= blocksize;
                dst += blocksize;
                src += blocksize;
                len -= blocksize;
index 93580bb8852c4b46432091e6f178fa3f0ed11157..5d0531f1115b18283d64a20018248733e07936a8 100644 (file)
@@ -60,28 +60,33 @@ struct digest_algorithm digest_null = {
        .final = digest_null_final,
 };
 
        .final = digest_null_final,
 };
 
-int cipher_null_setkey ( void *ctx __unused, const void *key __unused,
+int cipher_null_setkey ( struct cipher_algorithm *cipher __unused,
+                        void *ctx __unused, const void *key __unused,
                         size_t keylen __unused ) {
        /* Do nothing */
        return 0;
 }
 
                         size_t keylen __unused ) {
        /* Do nothing */
        return 0;
 }
 
-void cipher_null_setiv ( void *ctx __unused, const void *iv __unused,
+void cipher_null_setiv ( struct cipher_algorithm *cipher __unused,
+                        void *ctx __unused, const void *iv __unused,
                         size_t ivlen __unused ) {
        /* Do nothing */
 }
 
                         size_t ivlen __unused ) {
        /* Do nothing */
 }
 
-void cipher_null_encrypt ( void *ctx __unused, const void *src, void *dst,
+void cipher_null_encrypt ( struct cipher_algorithm *cipher __unused,
+                          void *ctx __unused, const void *src, void *dst,
                           size_t len ) {
        memcpy ( dst, src, len );
 }
 
                           size_t len ) {
        memcpy ( dst, src, len );
 }
 
-void cipher_null_decrypt ( void *ctx __unused, const void *src, void *dst,
+void cipher_null_decrypt ( struct cipher_algorithm *cipher __unused,
+                          void *ctx __unused, const void *src, void *dst,
                           size_t len ) {
        memcpy ( dst, src, len );
 }
 
                           size_t len ) {
        memcpy ( dst, src, len );
 }
 
-void cipher_null_auth ( void *ctx __unused, void *auth __unused ) {
+void cipher_null_auth ( struct cipher_algorithm *cipher __unused,
+                       void *ctx __unused, void *auth __unused ) {
        /* Do nothing */
 }
 
        /* Do nothing */
 }
 
index a7fad9829146383124f2b672fb856d598d84cd1f..938643e1becbbc7e654e2c06cae07bc068fcac9a 100644 (file)
@@ -580,12 +580,14 @@ static uint32_t des_rol28 ( uint32_t dword ) {
 /**
  * Set key
  *
 /**
  * Set key
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v key              Key
  * @v keylen           Key length
  * @ret rc             Return status code
  */
  * @v ctx              Context
  * @v key              Key
  * @v keylen           Key length
  * @ret rc             Return status code
  */
-static int des_setkey ( void *ctx, const void *key, size_t keylen ) {
+static int des_setkey ( struct cipher_algorithm *cipher __unused, void *ctx,
+                       const void *key, size_t keylen ) {
        struct des_context *des = ctx;
        union des_round_key *rkey = des->rkey;
        union des_block reg;
        struct des_context *des = ctx;
        union des_round_key *rkey = des->rkey;
        union des_block reg;
@@ -640,12 +642,14 @@ static int des_setkey ( void *ctx, const void *key, size_t keylen ) {
 /**
  * Encrypt data
  *
 /**
  * Encrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  */
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  */
-static void des_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
+static void des_encrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
+                         const void *src, void *dst, size_t len ) {
        struct des_context *des = ctx;
 
        /* Sanity check */
        struct des_context *des = ctx;
 
        /* Sanity check */
@@ -658,12 +662,14 @@ static void des_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
 /**
  * Decrypt data
  *
 /**
  * Decrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  */
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  */
-static void des_decrypt ( void *ctx, const void *src, void *dst, size_t len ) {
+static void des_decrypt ( struct cipher_algorithm *cipher __unused, void *ctx,
+                         const void *src, void *dst, size_t len ) {
        struct des_context *des = ctx;
 
        /* Sanity check */
        struct des_context *des = ctx;
 
        /* Sanity check */
index 73eef09c260249a84edc9d5fabb0cccb194a05d6..754900caef28bc370e4ccbbd3262b01c97e7b9a4 100644 (file)
@@ -34,17 +34,34 @@ FILE_SECBOOT ( PERMITTED );
  *
  */
 
  *
  */
 
+/**
+ * Set key
+ *
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
+ * @v key              Key
+ * @v keylen           Key length
+ * @ret rc             Return status code
+ */
+int ecb_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                const void *key, size_t keylen ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+
+       return cipher_setkey ( raw_cipher, ctx, key, keylen );
+}
+
 /**
  * Encrypt data
  *
 /**
  * Encrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
  * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data
  * @v len              Length of data
- * @v raw_cipher       Underlying cipher algorithm
  */
  */
-void ecb_encrypt ( void *ctx, const void *src, void *dst, size_t len,
-                  struct cipher_algorithm *raw_cipher ) {
+void ecb_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
        size_t blocksize = raw_cipher->blocksize;
 
        assert ( ( len % blocksize ) == 0 );
        size_t blocksize = raw_cipher->blocksize;
 
        assert ( ( len % blocksize ) == 0 );
@@ -60,14 +77,15 @@ void ecb_encrypt ( void *ctx, const void *src, void *dst, size_t len,
 /**
  * Decrypt data
  *
 /**
  * Decrypt data
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
  * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data
  * @v len              Length of data
- * @v raw_cipher       Underlying cipher algorithm
  */
  */
-void ecb_decrypt ( void *ctx, const void *src, void *dst, size_t len,
-                  struct cipher_algorithm *raw_cipher ) {
+void ecb_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
        size_t blocksize = raw_cipher->blocksize;
 
        assert ( ( len % blocksize ) == 0 );
        size_t blocksize = raw_cipher->blocksize;
 
        assert ( ( len % blocksize ) == 0 );
index b9c9d3a395c0aca72cb5fe9c58879d6e57e28b78..c0e32a32045630f9c262441aebc782ee0b948c9d 100644 (file)
@@ -309,30 +309,55 @@ static void gcm_multiply_key ( const union gcm_block *key,
 }
 
 /**
 }
 
 /**
- * Encrypt/decrypt/authenticate data
+ * Construct hash
  *
  * @v context          Context
  *
  * @v context          Context
+ * @v hash             Hash to fill in
+ */
+static void gcm_hash ( struct gcm_context *context, union gcm_block *hash ) {
+
+       /* Construct big-endian lengths block */
+       hash->len.add = cpu_to_be64 ( context->len.len.add );
+       hash->len.data = cpu_to_be64 ( context->len.len.data );
+       DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
+       DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
+
+       /* Update hash */
+       gcm_xor_block ( &context->hash, hash );
+       gcm_multiply_key ( &context->key, hash );
+       DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
+       DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
+}
+
+/**
+ * Encrypt/decrypt/authenticate data
+ *
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
  * @v src              Input data
  * @v dst              Output data, or NULL to process additional data
  * @v len              Length of data
  * @v flags            Operation flags
  */
  * @v src              Input data
  * @v dst              Output data, or NULL to process additional data
  * @v len              Length of data
  * @v flags            Operation flags
  */
-static void gcm_process ( struct gcm_context *context, const void *src,
-                         void *dst, size_t len, unsigned int flags ) {
+static void gcm_process ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
+       unsigned int flags = context->gcm.flags;
        union gcm_block tmp;
        uint64_t *total;
        size_t frag_len;
        unsigned int block;
 
        /* Calculate block number (for debugging) */
        union gcm_block tmp;
        uint64_t *total;
        size_t frag_len;
        unsigned int block;
 
        /* Calculate block number (for debugging) */
-       block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
+       block = ( ( ( context->gcm.len.len.add + 8 * sizeof ( tmp ) - 1 ) /
                    ( 8 * sizeof ( tmp ) ) ) +
                    ( 8 * sizeof ( tmp ) ) ) +
-                 ( ( context->len.len.data + 8 * sizeof ( tmp ) - 1 ) /
+                 ( ( context->gcm.len.len.data + 8 * sizeof ( tmp ) - 1 ) /
                    ( 8 * sizeof ( tmp ) ) ) + 1 );
 
        /* Update total length (in bits) */
        total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
                    ( 8 * sizeof ( tmp ) ) ) + 1 );
 
        /* Update total length (in bits) */
        total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
-                 &context->len.len.data : &context->len.len.add );
+                 &context->gcm.len.len.data : &context->gcm.len.len.add );
        *total += ( len * 8 );
 
        /* Process data */
        *total += ( len * 8 );
 
        /* Process data */
@@ -344,20 +369,22 @@ static void gcm_process ( struct gcm_context *context, const void *src,
                        frag_len = sizeof ( tmp );
 
                /* Update hash with input data */
                        frag_len = sizeof ( tmp );
 
                /* Update hash with input data */
-               gcm_xor ( src, &context->hash, &context->hash, frag_len );
+               gcm_xor ( src, &context->gcm.hash, &context->gcm.hash,
+                         frag_len );
 
                /* Encrypt/decrypt block, if applicable */
                if ( dst ) {
 
                        /* Increment counter */
 
                /* Encrypt/decrypt block, if applicable */
                if ( dst ) {
 
                        /* Increment counter */
-                       gcm_count ( &context->ctr, 1 );
+                       gcm_count ( &context->gcm.ctr, 1 );
 
                        /* Encrypt counter */
                        DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
 
                        /* Encrypt counter */
                        DBGC2 ( context, "GCM %p Y[%d]:\n", context, block );
-                       DBGC2_HDA ( context, 0, &context->ctr,
-                                   sizeof ( context->ctr ) );
-                       cipher_encrypt ( context->raw_cipher, &context->raw_ctx,
-                                        &context->ctr, &tmp, sizeof ( tmp ) );
+                       DBGC2_HDA ( context, 0, &context->gcm.ctr,
+                                   sizeof ( context->gcm.ctr ) );
+                       cipher_encrypt ( raw_cipher, &context->raw,
+                                        &context->gcm.ctr, &tmp,
+                                        sizeof ( tmp ) );
                        DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
                                context, block );
                        DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
                        DBGC2 ( context, "GCM %p E(K,Y[%d]):\n",
                                context, block );
                        DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
@@ -367,100 +394,53 @@ static void gcm_process ( struct gcm_context *context, const void *src,
                        dst += frag_len;
 
                        /* Update hash with encrypted data, if applicable */
                        dst += frag_len;
 
                        /* Update hash with encrypted data, if applicable */
-                       gcm_xor ( &tmp, &context->hash, &context->hash,
+                       gcm_xor ( &tmp, &context->gcm.hash, &context->gcm.hash,
                                  ( frag_len & flags ) );
                }
 
                /* Update hash */
                                  ( frag_len & flags ) );
                }
 
                /* Update hash */
-               gcm_multiply_key ( &context->key, &context->hash );
+               gcm_multiply_key ( &context->gcm.key, &context->gcm.hash );
                DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
                DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
-               DBGC2_HDA ( context, 0, &context->hash,
-                           sizeof ( context->hash ) );
+               DBGC2_HDA ( context, 0, &context->gcm.hash,
+                           sizeof ( context->gcm.hash ) );
        }
 }
 
        }
 }
 
-/**
- * Construct hash
- *
- * @v context          Context
- * @v hash             Hash to fill in
- */
-static void gcm_hash ( struct gcm_context *context, union gcm_block *hash ) {
-
-       /* Construct big-endian lengths block */
-       hash->len.add = cpu_to_be64 ( context->len.len.add );
-       hash->len.data = cpu_to_be64 ( context->len.len.data );
-       DBGC2 ( context, "GCM %p len(A)||len(C):\n", context );
-       DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
-
-       /* Update hash */
-       gcm_xor_block ( &context->hash, hash );
-       gcm_multiply_key ( &context->key, hash );
-       DBGC2 ( context, "GCM %p GHASH(H,A,C):\n", context );
-       DBGC2_HDA ( context, 0, hash, sizeof ( *hash ) );
-}
-
-/**
- * Construct tag
- *
- * @v context          Context
- * @v tag              Tag
- */
-void gcm_tag ( struct gcm_context *context, union gcm_block *tag ) {
-       union gcm_block tmp;
-       uint32_t offset;
-
-       /* Construct hash */
-       gcm_hash ( context, tag );
-
-       /* Construct encrypted initial counter value */
-       memcpy ( &tmp, &context->ctr, sizeof ( tmp ) );
-       offset = ( ( -context->len.len.data ) / ( 8 * sizeof ( tmp ) ) );
-       gcm_count ( &tmp, offset );
-       cipher_encrypt ( context->raw_cipher, &context->raw_ctx, &tmp,
-                        &tmp, sizeof ( tmp ) );
-       DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
-       DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
-
-       /* Construct tag */
-       gcm_xor_block ( &tmp, tag );
-       DBGC2 ( context, "GCM %p T:\n", context );
-       DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
-}
-
 /**
  * Set key
  *
 /**
  * Set key
  *
- * @v context          Context
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
  * @v key              Key
  * @v keylen           Key length
  * @v key              Key
  * @v keylen           Key length
- * @v raw_cipher       Underlying cipher
  * @ret rc             Return status code
  */
  * @ret rc             Return status code
  */
-int gcm_setkey ( struct gcm_context *context, const void *key, size_t keylen,
-                struct cipher_algorithm *raw_cipher ) {
+int gcm_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                const void *key, size_t keylen ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
        int rc;
 
        /* Initialise GCM context */
        int rc;
 
        /* Initialise GCM context */
-       memset ( context, 0, sizeof ( *context ) );
-       context->raw_cipher = raw_cipher;
+       memset ( &context->gcm, 0, sizeof ( context->gcm ) );
 
        /* Set underlying block cipher key */
 
        /* Set underlying block cipher key */
-       if ( ( rc = cipher_setkey ( raw_cipher, context->raw_ctx, key,
+       if ( ( rc = cipher_setkey ( raw_cipher, context->raw, key,
                                    keylen ) ) != 0 )
                return rc;
 
        /* Construct GCM hash key */
                                    keylen ) ) != 0 )
                return rc;
 
        /* Construct GCM hash key */
-       cipher_encrypt ( raw_cipher, context->raw_ctx, &context->ctr,
-                        &context->key, sizeof ( context->key ) );
+       cipher_encrypt ( raw_cipher, context->raw, &context->gcm.ctr,
+                        &context->gcm.key, sizeof ( context->gcm.key ) );
        DBGC2 ( context, "GCM %p H:\n", context );
        DBGC2 ( context, "GCM %p H:\n", context );
-       DBGC2_HDA ( context, 0, &context->key, sizeof ( context->key ) );
+       DBGC2_HDA ( context, 0, &context->gcm.key,
+                   sizeof ( context->gcm.key ) );
 
        /* Reset counter */
 
        /* Reset counter */
-       context->ctr.ctr.value = cpu_to_be32 ( 1 );
+       context->gcm.ctr.ctr.value = cpu_to_be32 ( 1 );
 
        /* Construct cached tables */
 
        /* Construct cached tables */
-       gcm_cache ( &context->key );
+       gcm_cache ( &context->gcm.key );
 
        return 0;
 }
 
        return 0;
 }
@@ -468,75 +448,114 @@ int gcm_setkey ( struct gcm_context *context, const void *key, size_t keylen,
 /**
  * Set initialisation vector
  *
 /**
  * Set initialisation vector
  *
+ * @v cipher           Cipher algorithm
  * @v ctx              Context
  * @v iv               Initialisation vector
  * @v ivlen            Initialisation vector length
  */
  * @v ctx              Context
  * @v iv               Initialisation vector
  * @v ivlen            Initialisation vector length
  */
-void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
+void gcm_setiv ( struct cipher_algorithm *cipher, void *ctx,
+                const void *iv, size_t ivlen ) {
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
 
        /* Reset non-key state */
 
        /* Reset non-key state */
-       memset ( context, 0, gcm_offset ( key ) );
+       memset ( &context->gcm, 0, gcm_offset ( key ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( hash ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( len ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( hash ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( len ) );
        build_assert ( gcm_offset ( key ) > gcm_offset ( ctr ) );
-       build_assert ( gcm_offset ( key ) < gcm_offset ( raw_cipher ) );
-       build_assert ( gcm_offset ( key ) < gcm_offset ( raw_ctx ) );
 
        /* Reset counter */
 
        /* Reset counter */
-       context->ctr.ctr.value = cpu_to_be32 ( 1 );
+       context->gcm.ctr.ctr.value = cpu_to_be32 ( 1 );
 
        /* Process initialisation vector */
 
        /* Process initialisation vector */
-       if ( ivlen == sizeof ( context->ctr.ctr.iv ) ) {
+       if ( ivlen == sizeof ( context->gcm.ctr.ctr.iv ) ) {
 
                /* Initialisation vector is exactly 96 bits, use it as-is */
 
                /* Initialisation vector is exactly 96 bits, use it as-is */
-               memcpy ( context->ctr.ctr.iv, iv, ivlen );
+               memcpy ( context->gcm.ctr.ctr.iv, iv, ivlen );
 
        } else {
 
                /* Calculate hash over initialisation vector */
 
        } else {
 
                /* Calculate hash over initialisation vector */
-               gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
-               gcm_hash ( context, &context->ctr );
-               assert ( context->len.len.add == 0 );
+               context->gcm.flags = GCM_FL_IV;
+               gcm_process ( cipher, ctx, iv, NULL, ivlen );
+               gcm_hash ( &context->gcm, &context->gcm.ctr );
+               assert ( context->gcm.len.len.add == 0 );
 
                /* Reset non-key, non-counter state */
 
                /* Reset non-key, non-counter state */
-               memset ( context, 0, gcm_offset ( ctr ) );
+               memset ( &context->gcm, 0, gcm_offset ( ctr ) );
                build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
                build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
                build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
                build_assert ( gcm_offset ( ctr ) > gcm_offset ( hash ) );
                build_assert ( gcm_offset ( ctr ) > gcm_offset ( len ) );
                build_assert ( gcm_offset ( ctr ) < gcm_offset ( key ) );
-               build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_cipher ) );
-               build_assert ( gcm_offset ( ctr ) < gcm_offset ( raw_ctx ) );
        }
 
        DBGC2 ( context, "GCM %p Y[0]:\n", context );
        }
 
        DBGC2 ( context, "GCM %p Y[0]:\n", context );
-       DBGC2_HDA ( context, 0, &context->ctr, sizeof ( context->ctr ) );
+       DBGC2_HDA ( context, 0, &context->gcm.ctr,
+                   sizeof ( context->gcm.ctr ) );
 }
 
 /**
  * Encrypt data
  *
 }
 
 /**
  * Encrypt data
  *
- * @v context          Context
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data, or NULL for additional data
  * @v len              Length of data
  */
  * @v src              Data to encrypt
  * @v dst              Buffer for encrypted data, or NULL for additional data
  * @v len              Length of data
  */
-void gcm_encrypt ( struct gcm_context *context, const void *src, void *dst,
-                  size_t len ) {
+void gcm_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
 
        /* Process data */
 
        /* Process data */
-       gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
+       context->gcm.flags = GCM_FL_ENCRYPT;
+       gcm_process ( cipher, ctx, src, dst, len );
 }
 
 /**
  * Decrypt data
  *
 }
 
 /**
  * Decrypt data
  *
- * @v context          Context
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data, or NULL for additional data
  * @v len              Length of data
  */
  * @v src              Data to decrypt
  * @v dst              Buffer for decrypted data, or NULL for additional data
  * @v len              Length of data
  */
-void gcm_decrypt ( struct gcm_context *context, const void *src, void *dst,
-                  size_t len ) {
+void gcm_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                  const void *src, void *dst, size_t len ) {
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
 
        /* Process data */
 
        /* Process data */
-       gcm_process ( context, src, dst, len, 0 );
+       context->gcm.flags = 0;
+       gcm_process ( cipher, ctx, src, dst, len );
+}
+
+/**
+ * Generate authentication tag
+ *
+ * @v cipher           Cipher algorithm
+ * @v ctx              Context
+ * @v auth             Authentication tag
+ */
+void gcm_auth ( struct cipher_algorithm *cipher, void *ctx, void *auth ) {
+       struct cipher_algorithm *raw_cipher = cipher->priv;
+       gcm_context_t ( cipher->ctxsize ) *context = ctx;
+       union gcm_block *tag = auth;
+       union gcm_block tmp;
+       uint32_t offset;
+
+       /* Construct hash */
+       gcm_hash ( &context->gcm, tag );
+
+       /* Construct encrypted initial counter value */
+       memcpy ( &tmp, &context->gcm.ctr, sizeof ( tmp ) );
+       offset = ( ( -context->gcm.len.len.data ) / ( 8 * sizeof ( tmp ) ) );
+       gcm_count ( &tmp, offset );
+       cipher_encrypt ( raw_cipher, &context->raw, &tmp, &tmp,
+                        sizeof ( tmp ) );
+       DBGC2 ( context, "GCM %p E(K,Y[0]):\n", context );
+       DBGC2_HDA ( context, 0, &tmp, sizeof ( tmp ) );
+
+       /* Construct tag */
+       gcm_xor_block ( &tmp, tag );
+       DBGC2 ( context, "GCM %p T:\n", context );
+       DBGC2_HDA ( context, 0, tag, sizeof ( *tag ) );
 }
 }
index 154fc5666cdf6f7e22c5bece06656e87e92a0fb8..11979f2e2ff2df2fddce64941b61d825ef29cc8f 100644 (file)
@@ -12,46 +12,21 @@ FILE_SECBOOT ( PERMITTED );
 
 #include <ipxe/crypto.h>
 
 
 #include <ipxe/crypto.h>
 
-/**
- * Set key
- *
- * @v ctx              Context
- * @v key              Key
- * @v keylen           Key length
- * @v raw_cipher       Underlying cipher algorithm
- * @v cbc_ctx          CBC context
- * @ret rc             Return status code
- */
-static inline int cbc_setkey ( void *ctx, const void *key, size_t keylen,
-                              struct cipher_algorithm *raw_cipher,
-                              void *cbc_ctx __unused ) {
-
-       return cipher_setkey ( raw_cipher, ctx, key, keylen );
-}
-
-/**
- * Set initialisation vector
- *
- * @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, size_t ivlen,
-                              struct cipher_algorithm *raw_cipher,
-                              void *cbc_ctx ) {
-       assert ( ivlen == raw_cipher->blocksize );
-       memcpy ( cbc_ctx, iv, raw_cipher->blocksize );
-}
-
-extern void cbc_encrypt ( void *ctx, const void *src, void *dst,
-                         size_t len, struct cipher_algorithm *raw_cipher,
-                         void *cbc_ctx );
-extern void cbc_decrypt ( void *ctx, const void *src, void *dst,
-                         size_t len, struct cipher_algorithm *raw_cipher,
-                         void *cbc_ctx );
+/** A cipher-block chaining mode context */
+#define cbc_context_t( blocksize, ctxsize )                            \
+       struct {                                                        \
+               uint8_t cbc[ (blocksize) ];                             \
+               uint8_t raw[ (ctxsize) - (blocksize) ];                 \
+       }
+
+extern int cbc_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                       const void *key, size_t keylen );
+extern void cbc_setiv ( struct cipher_algorithm *cipher, void *ctx,
+                       const void *iv, size_t ivlen );
+extern void cbc_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
+extern void cbc_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
 
 /**
  * Create a cipher-block chaining mode of behaviour of an existing cipher
 
 /**
  * Create a cipher-block chaining mode of behaviour of an existing cipher
@@ -64,45 +39,18 @@ extern void cbc_decrypt ( void *ctx, const void *src, void *dst,
  */
 #define CBC_CIPHER( _cbc_name, _cbc_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
  */
 #define CBC_CIPHER( _cbc_name, _cbc_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
-struct _cbc_name ## _context {                                         \
-       _raw_context raw_ctx;                                           \
-       uint8_t cbc_ctx[_blocksize];                                    \
-};                                                                     \
-static int _cbc_name ## _setkey ( void *ctx, const void *key,          \
-                                 size_t keylen ) {                     \
-       struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;         \
-       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,           \
-                                  size_t ivlen ) {                     \
-       struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;         \
-       cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, ivlen,             \
-                   &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );        \
-}                                                                      \
-static void _cbc_name ## _encrypt ( void *ctx, const void *src,                \
-                                   void *dst, size_t len ) {           \
-       struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;         \
-       cbc_encrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len,       \
-                     &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );      \
-}                                                                      \
-static void _cbc_name ## _decrypt ( void *ctx, const void *src,                \
-                                   void *dst, size_t len ) {           \
-       struct _cbc_name ## _context * _cbc_name ## _ctx = ctx;         \
-       cbc_decrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len,       \
-                     &_raw_cipher, &_cbc_name ## _ctx->cbc_ctx );      \
-}                                                                      \
 struct cipher_algorithm _cbc_cipher = {                                        \
        .name           = #_cbc_name,                                   \
 struct cipher_algorithm _cbc_cipher = {                                        \
        .name           = #_cbc_name,                                   \
-       .ctxsize        = sizeof ( struct _cbc_name ## _context ),      \
+       .ctxsize        = ( _blocksize + sizeof ( _raw_context ) ),     \
        .blocksize      = _blocksize,                                   \
        .alignsize      = _blocksize,                                   \
        .authsize       = 0,                                            \
        .blocksize      = _blocksize,                                   \
        .alignsize      = _blocksize,                                   \
        .authsize       = 0,                                            \
-       .setkey         = _cbc_name ## _setkey,                         \
-       .setiv          = _cbc_name ## _setiv,                          \
-       .encrypt        = _cbc_name ## _encrypt,                        \
-       .decrypt        = _cbc_name ## _decrypt,                        \
+       .setkey         = cbc_setkey,                                   \
+       .setiv          = cbc_setiv,                                    \
+       .encrypt        = cbc_encrypt,                                  \
+       .decrypt        = cbc_decrypt,                                  \
        .auth           = cipher_null_auth,                             \
        .auth           = cipher_null_auth,                             \
+       .priv           = &_raw_cipher,                                 \
 };
 
 #endif /* _IPXE_CBC_H */
 };
 
 #endif /* _IPXE_CBC_H */
index bf5bcc811d178f12f60977c82b550777725b038e..933103dfb2f9676c47342bd2cbb831124b8b4bf8 100644 (file)
@@ -82,21 +82,26 @@ struct cipher_algorithm {
        size_t authsize;
        /** Set key
         *
        size_t authsize;
        /** Set key
         *
+        * @v cipher    Cipher algorithm
         * @v ctx       Context
         * @v key       Key
         * @v keylen    Key length
         * @ret rc      Return status code
         */
         * @v ctx       Context
         * @v key       Key
         * @v keylen    Key length
         * @ret rc      Return status code
         */
-       int ( * setkey ) ( void *ctx, const void *key, size_t keylen );
+       int ( * setkey ) ( struct cipher_algorithm *cipher, void *ctx,
+                          const void *key, size_t keylen );
        /** Set initialisation vector
         *
        /** Set initialisation vector
         *
+        * @v cipher    Cipher algorithm
         * @v ctx       Context
         * @v iv        Initialisation vector
         * @v ivlen     Initialisation vector length
         */
         * @v ctx       Context
         * @v iv        Initialisation vector
         * @v ivlen     Initialisation vector length
         */
-       void ( * setiv ) ( void *ctx, const void *iv, size_t ivlen );
+       void ( * setiv ) ( struct cipher_algorithm *cipher, void *ctx,
+                          const void *iv, size_t ivlen );
        /** Encrypt data
         *
        /** Encrypt data
         *
+        * @v cipher    Cipher algorithm
         * @v ctx       Context
         * @v src       Data to encrypt
         * @v dst       Buffer for encrypted data, or NULL for additional data
         * @v ctx       Context
         * @v src       Data to encrypt
         * @v dst       Buffer for encrypted data, or NULL for additional data
@@ -104,10 +109,11 @@ struct cipher_algorithm {
         *
         * @v len is guaranteed to be a multiple of @c blocksize.
         */
         *
         * @v len is guaranteed to be a multiple of @c blocksize.
         */
-       void ( * encrypt ) ( void *ctx, const void *src, void *dst,
-                            size_t len );
+       void ( * encrypt ) ( struct cipher_algorithm *cipher, void *ctx,
+                            const void *src, void *dst, size_t len );
        /** Decrypt data
         *
        /** Decrypt data
         *
+        * @v cipher    Cipher algorithm
         * @v ctx       Context
         * @v src       Data to decrypt
         * @v dst       Buffer for decrypted data, or NULL for additional data
         * @v ctx       Context
         * @v src       Data to decrypt
         * @v dst       Buffer for decrypted data, or NULL for additional data
@@ -115,14 +121,18 @@ struct cipher_algorithm {
         *
         * @v len is guaranteed to be a multiple of @c blocksize.
         */
         *
         * @v len is guaranteed to be a multiple of @c blocksize.
         */
-       void ( * decrypt ) ( void *ctx, const void *src, void *dst,
-                            size_t len );
+       void ( * decrypt ) ( struct cipher_algorithm *cipher, void *ctx,
+                            const void *src, void *dst, size_t len );
        /** Generate authentication tag
         *
        /** Generate authentication tag
         *
+        * @v cipher    Cipher algorithm
         * @v ctx       Context
         * @v auth      Authentication tag
         */
         * @v ctx       Context
         * @v auth      Authentication tag
         */
-       void ( * auth ) ( void *ctx, void *auth );
+       void ( * auth ) ( struct cipher_algorithm *cipher, void *ctx,
+                         void *auth );
+       /** Algorithm private data */
+       void *priv;
 };
 
 /** A public key algorithm */
 };
 
 /** A public key algorithm */
@@ -283,19 +293,19 @@ digest_final ( struct digest_algorithm *digest, void *ctx, void *out ) {
 static inline __attribute__ (( always_inline )) int
 cipher_setkey ( struct cipher_algorithm *cipher, void *ctx,
                const void *key, size_t keylen ) {
 static inline __attribute__ (( always_inline )) int
 cipher_setkey ( struct cipher_algorithm *cipher, void *ctx,
                const void *key, size_t keylen ) {
-       return cipher->setkey ( ctx, key, keylen );
+       return cipher->setkey ( cipher, ctx, key, keylen );
 }
 
 static inline __attribute__ (( always_inline )) void
 cipher_setiv ( struct cipher_algorithm *cipher, void *ctx,
               const void *iv, size_t ivlen ) {
 }
 
 static inline __attribute__ (( always_inline )) void
 cipher_setiv ( struct cipher_algorithm *cipher, void *ctx,
               const void *iv, size_t ivlen ) {
-       cipher->setiv ( ctx, iv, ivlen );
+       cipher->setiv ( cipher, ctx, iv, ivlen );
 }
 
 static inline __attribute__ (( always_inline )) void
 cipher_encrypt ( struct cipher_algorithm *cipher, void *ctx,
                 const void *src, void *dst, size_t len ) {
 }
 
 static inline __attribute__ (( always_inline )) void
 cipher_encrypt ( struct cipher_algorithm *cipher, void *ctx,
                 const void *src, void *dst, size_t len ) {
-       cipher->encrypt ( ctx, src, dst, len );
+       cipher->encrypt ( cipher, ctx, src, dst, len );
 }
 #define cipher_encrypt( cipher, ctx, src, dst, len ) do {              \
        assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
 }
 #define cipher_encrypt( cipher, ctx, src, dst, len ) do {              \
        assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
@@ -305,7 +315,7 @@ cipher_encrypt ( struct cipher_algorithm *cipher, void *ctx,
 static inline __attribute__ (( always_inline )) void
 cipher_decrypt ( struct cipher_algorithm *cipher, void *ctx,
                 const void *src, void *dst, size_t len ) {
 static inline __attribute__ (( always_inline )) void
 cipher_decrypt ( struct cipher_algorithm *cipher, void *ctx,
                 const void *src, void *dst, size_t len ) {
-       cipher->decrypt ( ctx, src, dst, len );
+       cipher->decrypt ( cipher, ctx, src, dst, len );
 }
 #define cipher_decrypt( cipher, ctx, src, dst, len ) do {              \
        assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
 }
 #define cipher_decrypt( cipher, ctx, src, dst, len ) do {              \
        assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 );        \
@@ -314,7 +324,7 @@ cipher_decrypt ( struct cipher_algorithm *cipher, void *ctx,
 
 static inline __attribute__ (( always_inline )) void
 cipher_auth ( struct cipher_algorithm *cipher, void *ctx, void *auth ) {
 
 static inline __attribute__ (( always_inline )) void
 cipher_auth ( struct cipher_algorithm *cipher, void *ctx, void *auth ) {
-       cipher->auth ( ctx, auth );
+       cipher->auth ( cipher, ctx, auth );
 }
 
 static inline __attribute__ (( always_inline )) int
 }
 
 static inline __attribute__ (( always_inline )) int
@@ -402,13 +412,16 @@ extern void digest_null_update ( struct digest_algorithm *digest, void *ctx,
 extern void digest_null_final ( struct digest_algorithm *digest, void *ctx,
                                void *out );
 
 extern void digest_null_final ( struct digest_algorithm *digest, 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, 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,
-                                 size_t len );
-extern void cipher_null_auth ( void *ctx, void *auth );
+extern int cipher_null_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                               const void *key, size_t keylen );
+extern void cipher_null_setiv ( struct cipher_algorithm *cipehr, void *ctx,
+                               const void *iv, size_t ivlen );
+extern void cipher_null_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                                 const void *src, void *dst, size_t len );
+extern void cipher_null_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                                 const void *src, void *dst, size_t len );
+extern void cipher_null_auth ( struct cipher_algorithm *cipher, void *ctx,
+                              void *auth );
 
 extern int pubkey_null_encrypt ( const struct asn1_cursor *key,
                                 const struct asn1_cursor *plaintext,
 
 extern int pubkey_null_encrypt ( const struct asn1_cursor *key,
                                 const struct asn1_cursor *plaintext,
index c29602fca778551b27124340ee130652247739aa..791ab067c65db69c71d3f926220f077d7dd576f0 100644 (file)
@@ -12,13 +12,15 @@ FILE_SECBOOT ( PERMITTED );
 
 #include <ipxe/crypto.h>
 
 
 #include <ipxe/crypto.h>
 
-extern void ecb_encrypt ( void *ctx, const void *src, void *dst,
-                         size_t len, struct cipher_algorithm *raw_cipher );
-extern void ecb_decrypt ( void *ctx, const void *src, void *dst,
-                         size_t len, struct cipher_algorithm *raw_cipher );
+extern int ecb_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                       const void *key, size_t keylen );
+extern void ecb_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
+extern void ecb_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
 
 /**
 
 /**
- * Create a cipher-block chaining mode of behaviour of an existing cipher
+ * Create an electronic codebook mode of behaviour of an existing cipher
  *
  * @v _ecb_name                Name for the new ECB cipher
  * @v _ecb_cipher      New cipher algorithm
  *
  * @v _ecb_name                Name for the new ECB cipher
  * @v _ecb_cipher      New cipher algorithm
@@ -28,33 +30,18 @@ extern void ecb_decrypt ( void *ctx, const void *src, void *dst,
  */
 #define ECB_CIPHER( _ecb_name, _ecb_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
  */
 #define ECB_CIPHER( _ecb_name, _ecb_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
-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,           \
-                                 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 ) {           \
-       ecb_encrypt ( ctx, src, dst, len, &_raw_cipher );               \
-}                                                                      \
-static void _ecb_name ## _decrypt ( void *ctx, const void *src,                \
-                                   void *dst, size_t len ) {           \
-       ecb_decrypt ( ctx, src, dst, len, &_raw_cipher );               \
-}                                                                      \
 struct cipher_algorithm _ecb_cipher = {                                        \
        .name           = #_ecb_name,                                   \
        .ctxsize        = sizeof ( _raw_context ),                      \
        .blocksize      = _blocksize,                                   \
        .alignsize      = _blocksize,                                   \
        .authsize       = 0,                                            \
 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,                          \
-       .encrypt        = _ecb_name ## _encrypt,                        \
-       .decrypt        = _ecb_name ## _decrypt,                        \
+       .setkey         = ecb_setkey,                                   \
+       .setiv          = cipher_null_setiv,                            \
+       .encrypt        = ecb_encrypt,                                  \
+       .decrypt        = ecb_decrypt,                                  \
        .auth           = cipher_null_auth,                             \
        .auth           = cipher_null_auth,                             \
+       .priv           = &_raw_cipher,                                 \
 };
 
 #endif /* _IPXE_ECB_H */
 };
 
 #endif /* _IPXE_ECB_H */
index 5635a1031169cfd5e64987647e08de77329dd0f4..d794a7283bf06bddfae62a985029fc4ab853eed5 100644 (file)
@@ -53,21 +53,28 @@ struct gcm_context {
        union gcm_block ctr;
        /** Hash key (H) */
        union gcm_block key;
        union gcm_block ctr;
        /** Hash key (H) */
        union gcm_block key;
-       /** Underlying block cipher */
-       struct cipher_algorithm *raw_cipher;
-       /** Underlying block cipher context */
-       uint8_t raw_ctx[0];
+       /** Processing flags */
+       unsigned int flags;
 };
 
 };
 
-extern void gcm_tag ( struct gcm_context *context, union gcm_block *tag );
-extern int gcm_setkey ( struct gcm_context *context, const void *key,
-                       size_t keylen, struct cipher_algorithm *raw_cipher );
-extern void gcm_setiv ( struct gcm_context *context, const void *iv,
-                       size_t ivlen );
-extern void gcm_encrypt ( struct gcm_context *context, const void *src,
-                         void *dst, size_t len );
-extern void gcm_decrypt ( struct gcm_context *context, const void *src,
-                         void *dst, size_t len );
+/** A GCM mode context */
+#define gcm_context_t( ctxsize )                                       \
+       struct {                                                        \
+               struct gcm_context gcm;                                 \
+               uint8_t raw[ (ctxsize) -                                \
+                            sizeof ( struct gcm_context ) ];           \
+       }
+
+extern int gcm_setkey ( struct cipher_algorithm *cipher, void *ctx,
+                       const void *key, size_t keylen );
+extern void gcm_setiv ( struct cipher_algorithm *cipher, void *ctx,
+                       const void *iv, size_t ivlen );
+extern void gcm_encrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
+extern void gcm_decrypt ( struct cipher_algorithm *cipher, void *ctx,
+                         const void *src, void *dst, size_t len );
+extern void gcm_auth ( struct cipher_algorithm *cipher, void *ctx,
+                      void *auth );
 
 /**
  * Create a GCM mode of behaviour of an existing cipher
 
 /**
  * Create a GCM mode of behaviour of an existing cipher
@@ -80,52 +87,20 @@ extern void gcm_decrypt ( struct gcm_context *context, const void *src,
  */
 #define GCM_CIPHER( _gcm_name, _gcm_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
  */
 #define GCM_CIPHER( _gcm_name, _gcm_cipher, _raw_cipher, _raw_context, \
                    _blocksize )                                        \
-struct _gcm_name ## _context {                                         \
-       /** GCM context */                                              \
-       struct gcm_context gcm;                                         \
-       /** Underlying block cipher context */                          \
-       _raw_context raw;                                               \
-};                                                                     \
-static int _gcm_name ## _setkey ( void *ctx, const void *key,          \
-                                 size_t keylen ) {                     \
-       struct _gcm_name ## _context *context = ctx;                    \
-       build_assert ( _blocksize == sizeof ( context->gcm.key ) );     \
-       build_assert ( offsetof ( typeof ( *context ), gcm ) == 0 );    \
-       build_assert ( offsetof ( typeof ( *context ), raw ) ==         \
-                      offsetof ( typeof ( *context ), gcm.raw_ctx ) ); \
-       return gcm_setkey ( &context->gcm, key, keylen, &_raw_cipher ); \
-}                                                                      \
-static void _gcm_name ## _setiv ( void *ctx, const void *iv,           \
-                                 size_t ivlen ) {                      \
-       struct _gcm_name ## _context *context = ctx;                    \
-       gcm_setiv ( &context->gcm, iv, ivlen );                         \
-}                                                                      \
-static void _gcm_name ## _encrypt ( void *ctx, const void *src,                \
-                                   void *dst, size_t len ) {           \
-       struct _gcm_name ## _context *context = ctx;                    \
-       gcm_encrypt ( &context->gcm, src, dst, len );                   \
-}                                                                      \
-static void _gcm_name ## _decrypt ( void *ctx, const void *src,                \
-                                   void *dst, size_t len ) {           \
-       struct _gcm_name ## _context *context = ctx;                    \
-       gcm_decrypt ( &context->gcm, src, dst, len );                   \
-}                                                                      \
-static void _gcm_name ## _auth ( void *ctx, void *auth ) {             \
-       struct _gcm_name ## _context *context = ctx;                    \
-       union gcm_block *tag = auth;                                    \
-       gcm_tag ( &context->gcm, tag );                                 \
-}                                                                      \
+static_assert ( _blocksize == sizeof ( union gcm_block ) );            \
 struct cipher_algorithm _gcm_cipher = {                                        \
        .name           = #_gcm_name,                                   \
 struct cipher_algorithm _gcm_cipher = {                                        \
        .name           = #_gcm_name,                                   \
-       .ctxsize        = sizeof ( struct _gcm_name ## _context ),      \
+       .ctxsize        = ( sizeof ( struct gcm_context ) +             \
+                           sizeof ( _raw_context ) ),                  \
        .blocksize      = 1,                                            \
        .alignsize      = sizeof ( union gcm_block ),                   \
        .authsize       = sizeof ( union gcm_block ),                   \
        .blocksize      = 1,                                            \
        .alignsize      = sizeof ( union gcm_block ),                   \
        .authsize       = sizeof ( union gcm_block ),                   \
-       .setkey         = _gcm_name ## _setkey,                         \
-       .setiv          = _gcm_name ## _setiv,                          \
-       .encrypt        = _gcm_name ## _encrypt,                        \
-       .decrypt        = _gcm_name ## _decrypt,                        \
-       .auth           = _gcm_name ## _auth,                           \
+       .setkey         = gcm_setkey,                                   \
+       .setiv          = gcm_setiv,                                    \
+       .encrypt        = gcm_encrypt,                                  \
+       .decrypt        = gcm_decrypt,                                  \
+       .auth           = gcm_auth,                                     \
+       .priv           = &_raw_cipher,                                 \
 };
 
 #endif /* _IPXE_GCM_H */
 };
 
 #endif /* _IPXE_GCM_H */