* [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping
@ 2015-10-15 7:05 Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 1/3] crypto: add key wrapping block chaining mode Stephan Mueller
` (3 more replies)
0 siblings, 4 replies; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 7:05 UTC (permalink / raw)
To: herbert; +Cc: boris.brezillon, linux-crypto
Hi,
Changes v4:
* make patch 3/3 standalone by incorporating and updating patch
https://lkml.org/lkml/2015/6/16/342
Changes v3:
* split patch for easier review
* add support for full SGL handling in decrypt by adding a "fast-forward"
function
* significant simplification of code and removal of one memcpy per round
* use of scatterwalk API throughout code and removal of self-written code
* perform a full CAVS test with all AES implementations available on X86
(C, assembler and AES-NI)
Changes v2:
* Turn kw() into a blkcipher as suggested by Herbert Xu.
* Drop the support for user provided IV to initialize encrypt or
for performing the verify step during decrypt.
Stephan Mueller (3):
crypto: add key wrapping block chaining mode
crypto: keywrap - enable compilation
crypto: keywrap - add testmgr support
crypto/Kconfig | 7 +
crypto/Makefile | 1 +
crypto/keywrap.c | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
crypto/testmgr.c | 28 +++-
crypto/testmgr.h | 41 ++++++
5 files changed, 495 insertions(+), 1 deletion(-)
create mode 100644 crypto/keywrap.c
--
2.5.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/3] crypto: add key wrapping block chaining mode
2015-10-15 7:05 [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Stephan Mueller
@ 2015-10-15 7:06 ` Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 2/3] crypto: keywrap - enable compilation Stephan Mueller
` (2 subsequent siblings)
3 siblings, 0 replies; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 7:06 UTC (permalink / raw)
To: herbert; +Cc: boris.brezillon, linux-crypto
This patch implements the AES key wrapping as specified in
NIST SP800-38F and RFC3394.
The implementation covers key wrapping without padding.
IV handling: The caller does not provide an IV for encryption,
but must obtain the IV after encryption which would serve as the first
semblock in the ciphertext structure defined by SP800-38F. Conversely,
for decryption, the caller must provide the first semiblock of the data
as the IV and the following blocks as ciphertext.
The key wrapping is an authenticated decryption operation. The caller
will receive EBADMSG during decryption if the authentication failed.
Albeit the standards define the key wrapping for AES only, the template
can be used with any other block cipher that has a block size of 16
bytes. During initialization of the template, that condition is checked.
Any cipher not having a block size of 16 bytes will cause the
initialization to fail.
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/keywrap.c | 419 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 419 insertions(+)
create mode 100644 crypto/keywrap.c
diff --git a/crypto/keywrap.c b/crypto/keywrap.c
new file mode 100644
index 0000000..b1d106c
--- /dev/null
+++ b/crypto/keywrap.c
@@ -0,0 +1,419 @@
+/*
+ * Key Wrapping: RFC3394 / NIST SP800-38F
+ *
+ * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU General Public License, in which case the provisions of the GPL2
+ * are required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+/*
+ * Note for using key wrapping:
+ *
+ * * The result of the encryption operation is the ciphertext starting
+ * with the 2nd semiblock. The first semiblock is provided as the IV.
+ * The IV used to start the encryption operation is the default IV.
+ *
+ * * The input for the decryption is the first semiblock handed in as an
+ * IV. The ciphertext is the data starting with the 2nd semiblock. The
+ * return code of the decryption operation will be EBADMSG in case an
+ * integrity error occurs.
+ *
+ * To obtain the full result of an encryption as expected by SP800-38F, the
+ * caller must allocate a buffer of plaintext + 8 bytes:
+ *
+ * unsigned int datalen = ptlen + crypto_skcipher_ivsize(tfm);
+ * u8 data[datalen];
+ * u8 *iv = data;
+ * u8 *pt = data + crypto_skcipher_ivsize(tfm);
+ * <ensure that pt contains the plaintext of size ptlen>
+ * sg_init_one(&sg, ptdata, ptlen);
+ * skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv);
+ *
+ * ==> After encryption, data now contains full KW result as per SP800-38F.
+ *
+ * In case of decryption, ciphertext now already has the expected length
+ * and must be segmented appropriately:
+ *
+ * unsigned int datalen = CTLEN;
+ * u8 data[datalen];
+ * <ensure that data contains full ciphertext>
+ * u8 *iv = data;
+ * u8 *ct = data + crypto_skcipher_ivsize(tfm);
+ * unsigned int ctlen = datalen - crypto_skcipher_ivsize(tfm);
+ * sg_init_one(&sg, ctdata, ctlen);
+ * skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv);
+ *
+ * ==> After decryption (which hopefully does not return EBADMSG), the ct
+ * pointer now points to the plaintext of size ctlen.
+ *
+ * Note 2: KWP is not implemented as this would defy in-place operation.
+ * If somebody wants to wrap non-aligned data, he should simply pad
+ * the input with zeros to fill it up to the 8 byte boundary.
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <crypto/scatterwalk.h>
+#include <crypto/internal/skcipher.h>
+
+struct crypto_kw_ctx {
+ struct crypto_cipher *child;
+};
+
+struct crypto_kw_block {
+#define SEMIBSIZE 8
+ u8 A[SEMIBSIZE];
+ u8 R[SEMIBSIZE];
+};
+
+/* convert 64 bit integer into its string representation */
+static inline void crypto_kw_cpu_to_be64(u64 val, u8 *buf)
+{
+ __be64 *a = (__be64 *)buf;
+
+ *a = cpu_to_be64(val);
+}
+
+/*
+ * Fast forward the SGL to the "end" length minus SEMIBSIZE.
+ * The start in the SGL defined by the fast-forward is returned with
+ * the walk variable
+ */
+static void crypto_kw_scatterlist_ff(struct scatter_walk *walk,
+ struct scatterlist *sg,
+ unsigned int end)
+{
+ unsigned int skip = 0;
+
+ /* The caller should only operate on full SEMIBLOCKs. */
+ BUG_ON(end < SEMIBSIZE);
+
+ skip = end - SEMIBSIZE;
+ while (sg) {
+ if (sg->length > skip) {
+ scatterwalk_start(walk, sg);
+ scatterwalk_advance(walk, skip);
+ break;
+ } else
+ skip -= sg->length;
+
+ sg = sg_next(sg);
+ }
+}
+
+static int crypto_kw_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ struct crypto_cipher *child = ctx->child;
+
+ unsigned long alignmask = max_t(unsigned long, SEMIBSIZE,
+ crypto_cipher_alignmask(child));
+ unsigned int i;
+
+ u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask];
+ struct crypto_kw_block *block = (struct crypto_kw_block *)
+ PTR_ALIGN(blockbuf + 0, alignmask + 1);
+
+ u64 t = 6 * ((nbytes) >> 3);
+ struct scatterlist *lsrc, *ldst;
+ int ret = 0;
+
+ /*
+ * Require at least 2 semiblocks (note, the 3rd semiblock that is
+ * required by SP800-38F is the IV.
+ */
+ if (nbytes < (2 * SEMIBSIZE) || nbytes % SEMIBSIZE)
+ return -EINVAL;
+
+ /* Place the IV into block A */
+ memcpy(block->A, desc->info, SEMIBSIZE);
+
+ /*
+ * src scatterlist is read-only. dst scatterlist is r/w. During the
+ * first loop, lsrc points to src and ldst to dst. For any
+ * subsequent round, the code operates on dst only.
+ */
+ lsrc = src;
+ ldst = dst;
+
+ for (i = 0; i < 6; i++) {
+ u8 tbe_buffer[SEMIBSIZE + alignmask];
+ /* alignment for the crypto_xor and the _to_be64 operation */
+ u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1);
+ unsigned int tmp_nbytes = nbytes;
+ struct scatter_walk src_walk, dst_walk;
+
+ while (tmp_nbytes) {
+ /* move pointer by tmp_nbytes in the SGL */
+ crypto_kw_scatterlist_ff(&src_walk, lsrc, tmp_nbytes);
+ /* get the source block */
+ scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE,
+ false);
+
+ /* perform KW operation: get counter as byte string */
+ crypto_kw_cpu_to_be64(t, tbe);
+ /* perform KW operation: modify IV with counter */
+ crypto_xor(block->A, tbe, SEMIBSIZE);
+ t--;
+ /* perform KW operation: decrypt block */
+ crypto_cipher_decrypt_one(child, (u8*)block,
+ (u8*)block);
+
+ /* move pointer by tmp_nbytes in the SGL */
+ crypto_kw_scatterlist_ff(&dst_walk, ldst, tmp_nbytes);
+ /* Copy block->R into place */
+ scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE,
+ true);
+
+ tmp_nbytes -= SEMIBSIZE;
+ }
+
+ /* we now start to operate on the dst SGL only */
+ lsrc = dst;
+ ldst = dst;
+ }
+
+ /* Perform authentication check */
+ if (crypto_memneq("\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", block->A,
+ SEMIBSIZE))
+ ret = -EBADMSG;
+
+ memzero_explicit(&block, sizeof(struct crypto_kw_block));
+
+ return ret;
+}
+
+static int crypto_kw_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_blkcipher *tfm = desc->tfm;
+ struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm);
+ struct crypto_cipher *child = ctx->child;
+
+ unsigned long alignmask = max_t(unsigned long, SEMIBSIZE,
+ crypto_cipher_alignmask(child));
+ unsigned int i;
+
+ u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask];
+ struct crypto_kw_block *block = (struct crypto_kw_block *)
+ PTR_ALIGN(blockbuf + 0, alignmask + 1);
+
+ u64 t = 1;
+ struct scatterlist *lsrc, *ldst;
+
+ /*
+ * Require at least 2 semiblocks (note, the 3rd semiblock that is
+ * required by SP800-38F is the IV that occupies the first semiblock.
+ * This means that the dst memory must be one semiblock larger than src.
+ * Also ensure that the given data is aligned to semiblock.
+ */
+ if (nbytes < (2 * SEMIBSIZE) || nbytes % SEMIBSIZE)
+ return -EINVAL;
+
+ /*
+ * Place the predefined IV into block A -- for encrypt, the caller
+ * does not need to provide an IV, but he needs to fetch the final IV.
+ */
+ memcpy(block->A, "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", SEMIBSIZE);
+
+ /*
+ * src scatterlist is read-only. dst scatterlist is r/w. During the
+ * first loop, lsrc points to src and ldst to dst. For any
+ * subsequent round, the code operates on dst only.
+ */
+ lsrc = src;
+ ldst = dst;
+
+ for (i = 0; i < 6; i++) {
+ u8 tbe_buffer[SEMIBSIZE + alignmask];
+ u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1);
+ unsigned int tmp_nbytes = nbytes;
+ struct scatter_walk src_walk, dst_walk;
+
+ scatterwalk_start(&src_walk, lsrc);
+ scatterwalk_start(&dst_walk, ldst);
+
+ while (tmp_nbytes) {
+ /* get the source block */
+ scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE,
+ false);
+
+ /* perform KW operation: encrypt block */
+ crypto_cipher_encrypt_one(child, (u8 *)block,
+ (u8 *)block);
+ /* perform KW operation: get counter as byte string */
+ crypto_kw_cpu_to_be64(t, tbe);
+ /* perform KW operation: modify IV with counter */
+ crypto_xor(block->A, tbe, SEMIBSIZE);
+ t++;
+
+ /* Copy block->R into place */
+ scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE,
+ true);
+
+ tmp_nbytes -= SEMIBSIZE;
+ }
+
+ /* we now start to operate on the dst SGL only */
+ lsrc = dst;
+ ldst = dst;
+ }
+
+ /* establish the IV for the caller to pick up */
+ memcpy(desc->info, block->A, SEMIBSIZE);
+
+ memzero_explicit(&block, sizeof(struct crypto_kw_block));
+
+ return 0;
+}
+
+static int crypto_kw_setkey(struct crypto_tfm *parent, const u8 *key,
+ unsigned int keylen)
+{
+ struct crypto_kw_ctx *ctx = crypto_tfm_ctx(parent);
+ struct crypto_cipher *child = ctx->child;
+ int err;
+
+ crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_cipher_setkey(child, key, keylen);
+ crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
+ CRYPTO_TFM_RES_MASK);
+ return err;
+}
+
+static int crypto_kw_init_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
+ struct crypto_spawn *spawn = crypto_instance_ctx(inst);
+ struct crypto_kw_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct crypto_cipher *cipher;
+
+ cipher = crypto_spawn_cipher(spawn);
+ if (IS_ERR(cipher))
+ return PTR_ERR(cipher);
+
+ ctx->child = cipher;
+ return 0;
+}
+
+static void crypto_kw_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_kw_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_cipher(ctx->child);
+}
+
+static struct crypto_instance *crypto_kw_alloc(struct rtattr **tb)
+{
+ struct crypto_instance *inst = NULL;
+ struct crypto_alg *alg = NULL;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
+ if (err)
+ return ERR_PTR(err);
+
+ alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ if (IS_ERR(alg))
+ return ERR_CAST(alg);
+
+ inst = ERR_PTR(-EINVAL);
+ /* Section 5.1 requirement for KW */
+ if (alg->cra_blocksize != sizeof(struct crypto_kw_block))
+ goto err;
+
+ inst = crypto_alloc_instance("kw", alg);
+ if (IS_ERR(inst))
+ goto err;
+
+ inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
+ inst->alg.cra_priority = alg->cra_priority;
+ inst->alg.cra_blocksize = SEMIBSIZE;
+ inst->alg.cra_alignmask = 0;
+ inst->alg.cra_type = &crypto_blkcipher_type;
+ inst->alg.cra_blkcipher.ivsize = SEMIBSIZE;
+ inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
+ inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
+
+ inst->alg.cra_ctxsize = sizeof(struct crypto_kw_ctx);
+
+ inst->alg.cra_init = crypto_kw_init_tfm;
+ inst->alg.cra_exit = crypto_kw_exit_tfm;
+
+ inst->alg.cra_blkcipher.setkey = crypto_kw_setkey;
+ inst->alg.cra_blkcipher.encrypt = crypto_kw_encrypt;
+ inst->alg.cra_blkcipher.decrypt = crypto_kw_decrypt;
+
+err:
+ crypto_mod_put(alg);
+ return inst;
+}
+
+static void crypto_kw_free(struct crypto_instance *inst)
+{
+ crypto_drop_spawn(crypto_instance_ctx(inst));
+ kfree(inst);
+}
+
+static struct crypto_template crypto_kw_tmpl = {
+ .name = "kw",
+ .alloc = crypto_kw_alloc,
+ .free = crypto_kw_free,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_kw_init(void)
+{
+ return crypto_register_template(&crypto_kw_tmpl);
+}
+
+static void __exit crypto_kw_exit(void)
+{
+ crypto_unregister_template(&crypto_kw_tmpl);
+}
+
+module_init(crypto_kw_init);
+module_exit(crypto_kw_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
+MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)");
+MODULE_ALIAS_CRYPTO("kw");
--
2.5.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/3] crypto: keywrap - enable compilation
2015-10-15 7:05 [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 1/3] crypto: add key wrapping block chaining mode Stephan Mueller
@ 2015-10-15 7:06 ` Stephan Mueller
2015-10-15 7:07 ` [PATCH v4 3/3] crypto: keywrap - add testmgr support Stephan Mueller
2015-10-15 13:20 ` [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Herbert Xu
3 siblings, 0 replies; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 7:06 UTC (permalink / raw)
To: herbert; +Cc: boris.brezillon, linux-crypto
Hook keywrap source code into Kconfig and Makefile
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/Kconfig | 7 +++++++
crypto/Makefile | 1 +
2 files changed, 8 insertions(+)
diff --git a/crypto/Kconfig b/crypto/Kconfig
index fc93444..7240821 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -348,6 +348,13 @@ config CRYPTO_XTS
key size 256, 384 or 512 bits. This implementation currently
can't handle a sectorsize which is not a multiple of 16 bytes.
+config CRYPTO_KEYWRAP
+ tristate "Key wrapping support"
+ select CRYPTO_BLKCIPHER
+ help
+ Support for key wrapping (NIST SP800-38F / RFC3394) without
+ padding.
+
comment "Hash modes"
config CRYPTO_CMAC
diff --git a/crypto/Makefile b/crypto/Makefile
index d897e0b..f7aba92 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_CRYPTO_CTS) += cts.o
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
obj-$(CONFIG_CRYPTO_XTS) += xts.o
obj-$(CONFIG_CRYPTO_CTR) += ctr.o
+obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
obj-$(CONFIG_CRYPTO_GCM) += gcm.o
obj-$(CONFIG_CRYPTO_CCM) += ccm.o
obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o
--
2.5.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 7:05 [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 1/3] crypto: add key wrapping block chaining mode Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 2/3] crypto: keywrap - enable compilation Stephan Mueller
@ 2015-10-15 7:07 ` Stephan Mueller
2015-10-15 7:11 ` Herbert Xu
2015-10-15 13:20 ` [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Herbert Xu
3 siblings, 1 reply; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 7:07 UTC (permalink / raw)
To: herbert; +Cc: boris.brezillon, linux-crypto
The testmanager code for symmetric ciphers is extended to allow
verification of the IV after a cipher operation.
In addition, test vectors for kw(aes) for encryption and decryption are
added.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
crypto/testmgr.c | 28 +++++++++++++++++++++++++++-
crypto/testmgr.h | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 25032b0..e48b1c8 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1034,12 +1034,22 @@ static int __test_skcipher(struct crypto_skcipher *tfm, int enc,
q = data;
if (memcmp(q, template[i].result, template[i].rlen)) {
- pr_err("alg: skcipher%s: Test %d failed on %s for %s\n",
+ pr_err("alg: skcipher%s: Test %d failed (invalid result) on %s for %s\n",
d, j, e, algo);
hexdump(q, template[i].rlen);
ret = -EINVAL;
goto out;
}
+
+ if (template[i].iv_out &&
+ memcmp(iv, template[i].iv_out,
+ crypto_skcipher_ivsize(tfm))) {
+ pr_err("alg: skcipher%s: Test %d failed (invalid output IV) on %s for %s\n",
+ d, j, e, algo);
+ hexdump(iv, crypto_skcipher_ivsize(tfm));
+ ret = -EINVAL;
+ goto out;
+ }
}
j = 0;
@@ -3277,6 +3287,22 @@ static const struct alg_test_desc alg_test_descs[] = {
.fips_allowed = 1,
.test = alg_test_null,
}, {
+ .alg = "kw(aes)",
+ .test = alg_test_skcipher,
+ .fips_allowed = 1,
+ .suite = {
+ .cipher = {
+ .enc = {
+ .vecs = aes_kw_enc_tv_template,
+ .count = ARRAY_SIZE(aes_kw_enc_tv_template)
+ },
+ .dec = {
+ .vecs = aes_kw_dec_tv_template,
+ .count = ARRAY_SIZE(aes_kw_dec_tv_template)
+ }
+ }
+ }
+ }, {
.alg = "lrw(aes)",
.test = alg_test_skcipher,
.suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index e10582d..da0a8fd 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -67,6 +67,7 @@ struct hash_testvec {
struct cipher_testvec {
char *key;
char *iv;
+ char *iv_out;
char *input;
char *result;
unsigned short tap[MAX_TAP];
@@ -23832,6 +23833,46 @@ static struct aead_testvec rfc7539esp_dec_tv_template[] = {
};
/*
+ * All key wrapping test vectors taken from
+ * http://csrc.nist.gov/groups/STM/cavp/documents/mac/kwtestvectors.zip
+ *
+ * Note: as documented in keywrap.c, the ivout for encryption is the first
+ * semiblock of the ciphertext from the test vector. For decryption, iv is
+ * the first semiblock of the ciphertext.
+ */
+static struct cipher_testvec aes_kw_enc_tv_template[] = {
+ {
+ .key = "\x75\x75\xda\x3a\x93\x60\x7c\xc2"
+ "\xbf\xd8\xce\xc7\xaa\xdf\xd9\xa6",
+ .klen = 16,
+ .input = "\x42\x13\x6d\x3c\x38\x4a\x3e\xea"
+ "\xc9\x5a\x06\x6f\xd2\x8f\xed\x3f",
+ .ilen = 16,
+ .result = "\xf6\x85\x94\x81\x6f\x64\xca\xa3"
+ "\xf5\x6f\xab\xea\x25\x48\xf5\xfb",
+ .rlen = 16,
+ .iv_out = "\x03\x1f\x6b\xd7\xe6\x1e\x64\x3d",
+ },
+};
+
+static struct cipher_testvec aes_kw_dec_tv_template[] = {
+ {
+ .key = "\x80\xaa\x99\x73\x27\xa4\x80\x6b"
+ "\x6a\x7a\x41\xa5\x2b\x86\xc3\x71"
+ "\x03\x86\xf9\x32\x78\x6e\xf7\x96"
+ "\x76\xfa\xfb\x90\xb8\x26\x3c\x5f",
+ .klen = 32,
+ .input = "\xd3\x3d\x3d\x97\x7b\xf0\xa9\x15"
+ "\x59\xf9\x9c\x8a\xcd\x29\x3d\x43",
+ .ilen = 16,
+ .result = "\x0a\x25\x6b\xa7\x5c\xfa\x03\xaa"
+ "\xa0\x2b\xa9\x42\x03\xf1\x5b\xaa",
+ .rlen = 16,
+ .iv = "\x42\x3c\x96\x0d\x8a\x2a\xc4\xc1",
+ },
+};
+
+/*
* ANSI X9.31 Continuous Pseudo-Random Number Generator (AES mode)
* test vectors, taken from Appendix B.2.9 and B.2.10:
* http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf
--
2.5.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 7:07 ` [PATCH v4 3/3] crypto: keywrap - add testmgr support Stephan Mueller
@ 2015-10-15 7:11 ` Herbert Xu
2015-10-15 7:13 ` Stephan Mueller
0 siblings, 1 reply; 10+ messages in thread
From: Herbert Xu @ 2015-10-15 7:11 UTC (permalink / raw)
To: Stephan Mueller; +Cc: boris.brezillon, linux-crypto
On Thu, Oct 15, 2015 at 09:07:40AM +0200, Stephan Mueller wrote:
> The testmanager code for symmetric ciphers is extended to allow
> verification of the IV after a cipher operation.
>
> In addition, test vectors for kw(aes) for encryption and decryption are
> added.
>
> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> Signed-off-by: Stephan Mueller <smueller@chronox.de>
Oh I see. This patch can be applied without affect any existing
drivers. In that case I'll just apply Boris's original patch #1
and then reapply your previous submission.
Sorry for the confusion.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 7:11 ` Herbert Xu
@ 2015-10-15 7:13 ` Stephan Mueller
2015-10-15 7:17 ` Herbert Xu
0 siblings, 1 reply; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 7:13 UTC (permalink / raw)
To: Herbert Xu; +Cc: boris.brezillon, linux-crypto
Am Donnerstag, 15. Oktober 2015, 15:11:50 schrieb Herbert Xu:
Hi Herbert,
> On Thu, Oct 15, 2015 at 09:07:40AM +0200, Stephan Mueller wrote:
> > The testmanager code for symmetric ciphers is extended to allow
> > verification of the IV after a cipher operation.
> >
> > In addition, test vectors for kw(aes) for encryption and decryption are
> > added.
> >
> > Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
> > Signed-off-by: Stephan Mueller <smueller@chronox.de>
>
> Oh I see. This patch can be applied without affect any existing
> drivers. In that case I'll just apply Boris's original patch #1
> and then reapply your previous submission.
>
> Sorry for the confusion.
Note, I had to convert akcipher to skcipher -- thus, I guess you want to take
the newer patch and once you get back to Boris' original submission, just pull
the updates to the test vectors.
>
> Thanks,
--
Ciao
Stephan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 7:13 ` Stephan Mueller
@ 2015-10-15 7:17 ` Herbert Xu
2015-10-15 10:10 ` Stephan Mueller
0 siblings, 1 reply; 10+ messages in thread
From: Herbert Xu @ 2015-10-15 7:17 UTC (permalink / raw)
To: Stephan Mueller; +Cc: boris.brezillon, linux-crypto
On Thu, Oct 15, 2015 at 09:13:55AM +0200, Stephan Mueller wrote:
> Note, I had to convert akcipher to skcipher -- thus, I guess you want to take
> the newer patch and once you get back to Boris' original submission, just pull
> the updates to the test vectors.
What I'll do is apply Boris's patch #1, and then followed by your
v3. That should work, right?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 7:17 ` Herbert Xu
@ 2015-10-15 10:10 ` Stephan Mueller
2015-10-15 10:17 ` Herbert Xu
0 siblings, 1 reply; 10+ messages in thread
From: Stephan Mueller @ 2015-10-15 10:10 UTC (permalink / raw)
To: Herbert Xu; +Cc: boris.brezillon, linux-crypto
Am Donnerstag, 15. Oktober 2015, 15:17:12 schrieb Herbert Xu:
Hi Herbert,
> On Thu, Oct 15, 2015 at 09:13:55AM +0200, Stephan Mueller wrote:
> > Note, I had to convert akcipher to skcipher -- thus, I guess you want to
> > take the newer patch and once you get back to Boris' original submission,
> > just pull the updates to the test vectors.
>
> What I'll do is apply Boris's patch #1, and then followed by your
> v3. That should work, right?
That would work, if you replace the ablkcipher calls in Boris' patch with
skcipher to make that patch work.
My patch v3 3/3 works unchanged on top of Boris' patch as tested before
releasing v4 -- the patch 3/3 may have a hunk due to the changes in the number
of lines.
--
Ciao
Stephan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/3] crypto: keywrap - add testmgr support
2015-10-15 10:10 ` Stephan Mueller
@ 2015-10-15 10:17 ` Herbert Xu
0 siblings, 0 replies; 10+ messages in thread
From: Herbert Xu @ 2015-10-15 10:17 UTC (permalink / raw)
To: Stephan Mueller; +Cc: boris.brezillon, linux-crypto
On Thu, Oct 15, 2015 at 12:10:41PM +0200, Stephan Mueller wrote:
>
> That would work, if you replace the ablkcipher calls in Boris' patch with
> skcipher to make that patch work.
Right I'll do that when I merge the patch.
Thanks for the heads up.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping
2015-10-15 7:05 [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Stephan Mueller
` (2 preceding siblings ...)
2015-10-15 7:07 ` [PATCH v4 3/3] crypto: keywrap - add testmgr support Stephan Mueller
@ 2015-10-15 13:20 ` Herbert Xu
3 siblings, 0 replies; 10+ messages in thread
From: Herbert Xu @ 2015-10-15 13:20 UTC (permalink / raw)
To: Stephan Mueller; +Cc: boris.brezillon, linux-crypto
On Thu, Oct 15, 2015 at 09:05:48AM +0200, Stephan Mueller wrote:
> Hi,
>
> Changes v4:
> * make patch 3/3 standalone by incorporating and updating patch
> https://lkml.org/lkml/2015/6/16/342
>
> Changes v3:
> * split patch for easier review
> * add support for full SGL handling in decrypt by adding a "fast-forward"
> function
> * significant simplification of code and removal of one memcpy per round
> * use of scatterwalk API throughout code and removal of self-written code
> * perform a full CAVS test with all AES implementations available on X86
> (C, assembler and AES-NI)
v3 applied as we discussed earlier.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-10-15 13:20 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-15 7:05 [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 1/3] crypto: add key wrapping block chaining mode Stephan Mueller
2015-10-15 7:06 ` [PATCH v4 2/3] crypto: keywrap - enable compilation Stephan Mueller
2015-10-15 7:07 ` [PATCH v4 3/3] crypto: keywrap - add testmgr support Stephan Mueller
2015-10-15 7:11 ` Herbert Xu
2015-10-15 7:13 ` Stephan Mueller
2015-10-15 7:17 ` Herbert Xu
2015-10-15 10:10 ` Stephan Mueller
2015-10-15 10:17 ` Herbert Xu
2015-10-15 13:20 ` [PATCH v4 0/3] SP800-38F / RFC3394 key wrapping Herbert Xu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox