You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto update from Herbert Xu:
"API:
- Add support for cipher output IVs in testmgr
- Add missing crypto_ahash_blocksize helper
- Mark authenc and des ciphers as not allowed under FIPS.
Algorithms:
- Add CRC support to 842 compression
- Add keywrap algorithm
- A number of changes to the akcipher interface:
+ Separate functions for setting public/private keys.
+ Use SG lists.
Drivers:
- Add Intel SHA Extension optimised SHA1 and SHA256
- Use dma_map_sg instead of custom functions in crypto drivers
- Add support for STM32 RNG
- Add support for ST RNG
- Add Device Tree support to exynos RNG driver
- Add support for mxs-dcp crypto device on MX6SL
- Add xts(aes) support to caam
- Add ctr(aes) and xts(aes) support to qat
- A large set of fixes from Russell King for the marvell/cesa driver"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (115 commits)
crypto: asymmetric_keys - Fix unaligned access in x509_get_sig_params()
crypto: akcipher - Don't #include crypto/public_key.h as the contents aren't used
hwrng: exynos - Add Device Tree support
hwrng: exynos - Fix missing configuration after suspend to RAM
hwrng: exynos - Add timeout for waiting on init done
dt-bindings: rng: Describe Exynos4 PRNG bindings
crypto: marvell/cesa - use __le32 for hardware descriptors
crypto: marvell/cesa - fix missing cpu_to_le32() in mv_cesa_dma_add_op()
crypto: marvell/cesa - use memcpy_fromio()/memcpy_toio()
crypto: marvell/cesa - use gfp_t for gfp flags
crypto: marvell/cesa - use dma_addr_t for cur_dma
crypto: marvell/cesa - use readl_relaxed()/writel_relaxed()
crypto: caam - fix indentation of close braces
crypto: caam - only export the state we really need to export
crypto: caam - fix non-block aligned hash calculation
crypto: caam - avoid needlessly saving and restoring caam_hash_ctx
crypto: caam - print errno code when hash registration fails
crypto: marvell/cesa - fix memory leak
crypto: marvell/cesa - fix first-fragment handling in mv_cesa_ahash_dma_last_req()
crypto: marvell/cesa - rearrange handling for sw padded hashes
...
This commit is contained in:
+13
-4
@@ -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
|
||||
@@ -597,17 +604,18 @@ config CRYPTO_SHA1
|
||||
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
|
||||
|
||||
config CRYPTO_SHA1_SSSE3
|
||||
tristate "SHA1 digest algorithm (SSSE3/AVX/AVX2)"
|
||||
tristate "SHA1 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
|
||||
using Supplemental SSE3 (SSSE3) instructions or Advanced Vector
|
||||
Extensions (AVX/AVX2), when available.
|
||||
Extensions (AVX/AVX2) or SHA-NI(SHA Extensions New Instructions),
|
||||
when available.
|
||||
|
||||
config CRYPTO_SHA256_SSSE3
|
||||
tristate "SHA256 digest algorithm (SSSE3/AVX/AVX2)"
|
||||
tristate "SHA256 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_SHA256
|
||||
select CRYPTO_HASH
|
||||
@@ -615,7 +623,8 @@ config CRYPTO_SHA256_SSSE3
|
||||
SHA-256 secure hash standard (DFIPS 180-2) implemented
|
||||
using Supplemental SSE3 (SSSE3) instructions, or Advanced Vector
|
||||
Extensions version 1 (AVX1), or Advanced Vector Extensions
|
||||
version 2 (AVX2) instructions, when available.
|
||||
version 2 (AVX2) instructions, or SHA-NI (SHA Extensions New
|
||||
Instructions) when available.
|
||||
|
||||
config CRYPTO_SHA512_SSSE3
|
||||
tristate "SHA512 digest algorithm (SSSE3/AVX/AVX2)"
|
||||
|
||||
+7
-3
@@ -31,10 +31,13 @@ obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
|
||||
obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
|
||||
obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
|
||||
|
||||
$(obj)/rsakey-asn1.o: $(obj)/rsakey-asn1.c $(obj)/rsakey-asn1.h
|
||||
clean-files += rsakey-asn1.c rsakey-asn1.h
|
||||
$(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
|
||||
$(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
|
||||
clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
|
||||
clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
|
||||
|
||||
rsa_generic-y := rsakey-asn1.o
|
||||
rsa_generic-y := rsapubkey-asn1.o
|
||||
rsa_generic-y += rsaprivkey-asn1.o
|
||||
rsa_generic-y += rsa.o
|
||||
rsa_generic-y += rsa_helper.o
|
||||
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
|
||||
@@ -67,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
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <linux/cryptouser.h>
|
||||
#include <net/netlink.h>
|
||||
#include <crypto/akcipher.h>
|
||||
#include <crypto/public_key.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
|
||||
@@ -49,11 +49,12 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
|
||||
sinfo->sig.digest_size = digest_size = crypto_shash_digestsize(tfm);
|
||||
|
||||
ret = -ENOMEM;
|
||||
digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
|
||||
digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,
|
||||
GFP_KERNEL);
|
||||
if (!digest)
|
||||
goto error_no_desc;
|
||||
|
||||
desc = digest + digest_size;
|
||||
desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
|
||||
desc->tfm = tfm;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
|
||||
@@ -546,9 +546,9 @@ int x509_decode_time(time64_t *_t, size_t hdrlen,
|
||||
if (year < 1970 ||
|
||||
mon < 1 || mon > 12 ||
|
||||
day < 1 || day > mon_len ||
|
||||
hour < 0 || hour > 23 ||
|
||||
min < 0 || min > 59 ||
|
||||
sec < 0 || sec > 59)
|
||||
hour > 23 ||
|
||||
min > 59 ||
|
||||
sec > 59)
|
||||
goto invalid_time;
|
||||
|
||||
*_t = mktime64(year, mon, day, hour, min, sec);
|
||||
|
||||
@@ -194,14 +194,15 @@ int x509_get_sig_params(struct x509_certificate *cert)
|
||||
* digest storage space.
|
||||
*/
|
||||
ret = -ENOMEM;
|
||||
digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
|
||||
digest = kzalloc(ALIGN(digest_size, __alignof__(*desc)) + desc_size,
|
||||
GFP_KERNEL);
|
||||
if (!digest)
|
||||
goto error;
|
||||
|
||||
cert->sig.digest = digest;
|
||||
cert->sig.digest_size = digest_size;
|
||||
|
||||
desc = digest + digest_size;
|
||||
desc = PTR_ALIGN(digest + digest_size, __alignof__(*desc));
|
||||
desc->tfm = tfm;
|
||||
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
|
||||
@@ -98,10 +98,6 @@ void jent_get_nstime(__u64 *out)
|
||||
* If random_get_entropy does not return a value (which is possible on,
|
||||
* for example, MIPS), invoke __getnstimeofday
|
||||
* hoping that there are timers we can work with.
|
||||
*
|
||||
* The list of available timers can be obtained from
|
||||
* /sys/devices/system/clocksource/clocksource0/available_clocksource
|
||||
* and are registered with clocksource_register()
|
||||
*/
|
||||
if ((0 == tmp) &&
|
||||
(0 == __getnstimeofday(&ts))) {
|
||||
|
||||
@@ -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");
|
||||
+49
-34
@@ -97,24 +97,21 @@ static int rsa_enc(struct akcipher_request *req)
|
||||
goto err_free_c;
|
||||
}
|
||||
|
||||
m = mpi_read_raw_data(req->src, req->src_len);
|
||||
if (!m) {
|
||||
ret = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
m = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||
if (!m)
|
||||
goto err_free_c;
|
||||
}
|
||||
|
||||
ret = _rsa_enc(pkey, c, m);
|
||||
if (ret)
|
||||
goto err_free_m;
|
||||
|
||||
ret = mpi_read_buffer(c, req->dst, req->dst_len, &req->dst_len, &sign);
|
||||
ret = mpi_write_to_sgl(c, req->dst, &req->dst_len, &sign);
|
||||
if (ret)
|
||||
goto err_free_m;
|
||||
|
||||
if (sign < 0) {
|
||||
if (sign < 0)
|
||||
ret = -EBADMSG;
|
||||
goto err_free_m;
|
||||
}
|
||||
|
||||
err_free_m:
|
||||
mpi_free(m);
|
||||
@@ -145,25 +142,21 @@ static int rsa_dec(struct akcipher_request *req)
|
||||
goto err_free_m;
|
||||
}
|
||||
|
||||
c = mpi_read_raw_data(req->src, req->src_len);
|
||||
if (!c) {
|
||||
ret = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
c = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||
if (!c)
|
||||
goto err_free_m;
|
||||
}
|
||||
|
||||
ret = _rsa_dec(pkey, m, c);
|
||||
if (ret)
|
||||
goto err_free_c;
|
||||
|
||||
ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign);
|
||||
ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
|
||||
if (ret)
|
||||
goto err_free_c;
|
||||
|
||||
if (sign < 0) {
|
||||
if (sign < 0)
|
||||
ret = -EBADMSG;
|
||||
goto err_free_c;
|
||||
}
|
||||
|
||||
err_free_c:
|
||||
mpi_free(c);
|
||||
err_free_m:
|
||||
@@ -193,24 +186,21 @@ static int rsa_sign(struct akcipher_request *req)
|
||||
goto err_free_s;
|
||||
}
|
||||
|
||||
m = mpi_read_raw_data(req->src, req->src_len);
|
||||
if (!m) {
|
||||
ret = -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
m = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||
if (!m)
|
||||
goto err_free_s;
|
||||
}
|
||||
|
||||
ret = _rsa_sign(pkey, s, m);
|
||||
if (ret)
|
||||
goto err_free_m;
|
||||
|
||||
ret = mpi_read_buffer(s, req->dst, req->dst_len, &req->dst_len, &sign);
|
||||
ret = mpi_write_to_sgl(s, req->dst, &req->dst_len, &sign);
|
||||
if (ret)
|
||||
goto err_free_m;
|
||||
|
||||
if (sign < 0) {
|
||||
if (sign < 0)
|
||||
ret = -EBADMSG;
|
||||
goto err_free_m;
|
||||
}
|
||||
|
||||
err_free_m:
|
||||
mpi_free(m);
|
||||
@@ -241,7 +231,8 @@ static int rsa_verify(struct akcipher_request *req)
|
||||
goto err_free_m;
|
||||
}
|
||||
|
||||
s = mpi_read_raw_data(req->src, req->src_len);
|
||||
ret = -ENOMEM;
|
||||
s = mpi_read_raw_from_sgl(req->src, req->src_len);
|
||||
if (!s) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_m;
|
||||
@@ -251,14 +242,12 @@ static int rsa_verify(struct akcipher_request *req)
|
||||
if (ret)
|
||||
goto err_free_s;
|
||||
|
||||
ret = mpi_read_buffer(m, req->dst, req->dst_len, &req->dst_len, &sign);
|
||||
ret = mpi_write_to_sgl(m, req->dst, &req->dst_len, &sign);
|
||||
if (ret)
|
||||
goto err_free_s;
|
||||
|
||||
if (sign < 0) {
|
||||
if (sign < 0)
|
||||
ret = -EBADMSG;
|
||||
goto err_free_s;
|
||||
}
|
||||
|
||||
err_free_s:
|
||||
mpi_free(s);
|
||||
@@ -282,13 +271,13 @@ static int rsa_check_key_length(unsigned int len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
||||
unsigned int keylen)
|
||||
static int rsa_set_pub_key(struct crypto_akcipher *tfm, const void *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
ret = rsa_parse_key(pkey, key, keylen);
|
||||
ret = rsa_parse_pub_key(pkey, key, keylen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -299,6 +288,30 @@ static int rsa_setkey(struct crypto_akcipher *tfm, const void *key,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||
int ret;
|
||||
|
||||
ret = rsa_parse_priv_key(pkey, key, keylen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rsa_check_key_length(mpi_get_size(pkey->n) << 3)) {
|
||||
rsa_free_key(pkey);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rsa_max_size(struct crypto_akcipher *tfm)
|
||||
{
|
||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||
|
||||
return pkey->n ? mpi_get_size(pkey->n) : -EINVAL;
|
||||
}
|
||||
|
||||
static void rsa_exit_tfm(struct crypto_akcipher *tfm)
|
||||
{
|
||||
struct rsa_key *pkey = akcipher_tfm_ctx(tfm);
|
||||
@@ -311,7 +324,9 @@ static struct akcipher_alg rsa = {
|
||||
.decrypt = rsa_dec,
|
||||
.sign = rsa_sign,
|
||||
.verify = rsa_verify,
|
||||
.setkey = rsa_setkey,
|
||||
.set_priv_key = rsa_set_priv_key,
|
||||
.set_pub_key = rsa_set_pub_key,
|
||||
.max_size = rsa_max_size,
|
||||
.exit = rsa_exit_tfm,
|
||||
.base = {
|
||||
.cra_name = "rsa",
|
||||
|
||||
+35
-7
@@ -15,7 +15,8 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/fips.h>
|
||||
#include <crypto/internal/rsa.h>
|
||||
#include "rsakey-asn1.h"
|
||||
#include "rsapubkey-asn1.h"
|
||||
#include "rsaprivkey-asn1.h"
|
||||
|
||||
int rsa_get_n(void *context, size_t hdrlen, unsigned char tag,
|
||||
const void *value, size_t vlen)
|
||||
@@ -94,8 +95,8 @@ void rsa_free_key(struct rsa_key *key)
|
||||
EXPORT_SYMBOL_GPL(rsa_free_key);
|
||||
|
||||
/**
|
||||
* rsa_parse_key() - extracts an rsa key from BER encoded buffer
|
||||
* and stores it in the provided struct rsa_key
|
||||
* rsa_parse_pub_key() - extracts an rsa public key from BER encoded buffer
|
||||
* and stores it in the provided struct rsa_key
|
||||
*
|
||||
* @rsa_key: struct rsa_key key representation
|
||||
* @key: key in BER format
|
||||
@@ -103,13 +104,13 @@ EXPORT_SYMBOL_GPL(rsa_free_key);
|
||||
*
|
||||
* Return: 0 on success or error code in case of error
|
||||
*/
|
||||
int rsa_parse_key(struct rsa_key *rsa_key, const void *key,
|
||||
unsigned int key_len)
|
||||
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
free_mpis(rsa_key);
|
||||
ret = asn1_ber_decoder(&rsakey_decoder, rsa_key, key, key_len);
|
||||
ret = asn1_ber_decoder(&rsapubkey_decoder, rsa_key, key, key_len);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
@@ -118,4 +119,31 @@ error:
|
||||
free_mpis(rsa_key);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rsa_parse_key);
|
||||
EXPORT_SYMBOL_GPL(rsa_parse_pub_key);
|
||||
|
||||
/**
|
||||
* rsa_parse_pub_key() - extracts an rsa private key from BER encoded buffer
|
||||
* and stores it in the provided struct rsa_key
|
||||
*
|
||||
* @rsa_key: struct rsa_key key representation
|
||||
* @key: key in BER format
|
||||
* @key_len: length of key
|
||||
*
|
||||
* Return: 0 on success or error code in case of error
|
||||
*/
|
||||
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
|
||||
unsigned int key_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
free_mpis(rsa_key);
|
||||
ret = asn1_ber_decoder(&rsaprivkey_decoder, rsa_key, key, key_len);
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
free_mpis(rsa_key);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rsa_parse_priv_key);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
RsaKey ::= SEQUENCE {
|
||||
n INTEGER ({ rsa_get_n }),
|
||||
e INTEGER ({ rsa_get_e }),
|
||||
d INTEGER ({ rsa_get_d })
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
RsaPrivKey ::= SEQUENCE {
|
||||
version INTEGER,
|
||||
n INTEGER ({ rsa_get_n }),
|
||||
e INTEGER ({ rsa_get_e }),
|
||||
d INTEGER ({ rsa_get_d }),
|
||||
prime1 INTEGER,
|
||||
prime2 INTEGER,
|
||||
exponent1 INTEGER,
|
||||
exponent2 INTEGER,
|
||||
coefficient INTEGER
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
RsaPubKey ::= SEQUENCE {
|
||||
n INTEGER ({ rsa_get_n }),
|
||||
e INTEGER ({ rsa_get_e })
|
||||
}
|
||||
+2
-2
@@ -91,7 +91,7 @@ static void crypto_exit_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
||||
crypto_free_blkcipher(*ctx);
|
||||
}
|
||||
|
||||
int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
||||
static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_alg *calg = tfm->__crt_alg;
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
@@ -182,7 +182,7 @@ static void crypto_exit_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
||||
crypto_free_ablkcipher(*ctx);
|
||||
}
|
||||
|
||||
int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
||||
static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_alg *calg = tfm->__crt_alg;
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
|
||||
+13
-4
@@ -48,6 +48,8 @@
|
||||
#define ENCRYPT 1
|
||||
#define DECRYPT 0
|
||||
|
||||
#define MAX_DIGEST_SIZE 64
|
||||
|
||||
/*
|
||||
* return a string with the driver name
|
||||
*/
|
||||
@@ -950,7 +952,7 @@ static void test_ahash_speed(const char *algo, unsigned int secs,
|
||||
struct tcrypt_result tresult;
|
||||
struct ahash_request *req;
|
||||
struct crypto_ahash *tfm;
|
||||
static char output[1024];
|
||||
char *output;
|
||||
int i, ret;
|
||||
|
||||
tfm = crypto_alloc_ahash(algo, 0, 0);
|
||||
@@ -963,9 +965,9 @@ static void test_ahash_speed(const char *algo, unsigned int secs,
|
||||
printk(KERN_INFO "\ntesting speed of async %s (%s)\n", algo,
|
||||
get_driver_name(crypto_ahash, tfm));
|
||||
|
||||
if (crypto_ahash_digestsize(tfm) > sizeof(output)) {
|
||||
pr_err("digestsize(%u) > outputbuffer(%zu)\n",
|
||||
crypto_ahash_digestsize(tfm), sizeof(output));
|
||||
if (crypto_ahash_digestsize(tfm) > MAX_DIGEST_SIZE) {
|
||||
pr_err("digestsize(%u) > %d\n", crypto_ahash_digestsize(tfm),
|
||||
MAX_DIGEST_SIZE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -980,6 +982,10 @@ static void test_ahash_speed(const char *algo, unsigned int secs,
|
||||
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
tcrypt_complete, &tresult);
|
||||
|
||||
output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
|
||||
if (!output)
|
||||
goto out_nomem;
|
||||
|
||||
for (i = 0; speed[i].blen != 0; i++) {
|
||||
if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
|
||||
pr_err("template (%u) too big for tvmem (%lu)\n",
|
||||
@@ -1006,6 +1012,9 @@ static void test_ahash_speed(const char *algo, unsigned int secs,
|
||||
}
|
||||
}
|
||||
|
||||
kfree(output);
|
||||
|
||||
out_nomem:
|
||||
ahash_request_free(req);
|
||||
|
||||
out:
|
||||
|
||||
+47
-36
@@ -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;
|
||||
@@ -1845,34 +1855,34 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
||||
struct tcrypt_result result;
|
||||
unsigned int out_len_max, out_len = 0;
|
||||
int err = -ENOMEM;
|
||||
struct scatterlist src, dst, src_tab[2];
|
||||
|
||||
req = akcipher_request_alloc(tfm, GFP_KERNEL);
|
||||
if (!req)
|
||||
return err;
|
||||
|
||||
init_completion(&result.completion);
|
||||
err = crypto_akcipher_setkey(tfm, vecs->key, vecs->key_len);
|
||||
|
||||
if (vecs->public_key_vec)
|
||||
err = crypto_akcipher_set_pub_key(tfm, vecs->key,
|
||||
vecs->key_len);
|
||||
else
|
||||
err = crypto_akcipher_set_priv_key(tfm, vecs->key,
|
||||
vecs->key_len);
|
||||
if (err)
|
||||
goto free_req;
|
||||
|
||||
akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
|
||||
out_len);
|
||||
/* expect this to fail, and update the required buf len */
|
||||
crypto_akcipher_encrypt(req);
|
||||
out_len = req->dst_len;
|
||||
if (!out_len) {
|
||||
err = -EINVAL;
|
||||
goto free_req;
|
||||
}
|
||||
|
||||
out_len_max = out_len;
|
||||
err = -ENOMEM;
|
||||
out_len_max = crypto_akcipher_maxsize(tfm);
|
||||
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
|
||||
if (!outbuf_enc)
|
||||
goto free_req;
|
||||
|
||||
akcipher_request_set_crypt(req, vecs->m, outbuf_enc, vecs->m_size,
|
||||
out_len);
|
||||
sg_init_table(src_tab, 2);
|
||||
sg_set_buf(&src_tab[0], vecs->m, 8);
|
||||
sg_set_buf(&src_tab[1], vecs->m + 8, vecs->m_size - 8);
|
||||
sg_init_one(&dst, outbuf_enc, out_len_max);
|
||||
akcipher_request_set_crypt(req, src_tab, &dst, vecs->m_size,
|
||||
out_len_max);
|
||||
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
tcrypt_complete, &result);
|
||||
|
||||
@@ -1882,13 +1892,13 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
||||
pr_err("alg: rsa: encrypt test failed. err %d\n", err);
|
||||
goto free_all;
|
||||
}
|
||||
if (out_len != vecs->c_size) {
|
||||
if (req->dst_len != vecs->c_size) {
|
||||
pr_err("alg: rsa: encrypt test failed. Invalid output len\n");
|
||||
err = -EINVAL;
|
||||
goto free_all;
|
||||
}
|
||||
/* verify that encrypted message is equal to expected */
|
||||
if (memcmp(vecs->c, outbuf_enc, vecs->c_size)) {
|
||||
if (memcmp(vecs->c, sg_virt(req->dst), vecs->c_size)) {
|
||||
pr_err("alg: rsa: encrypt test failed. Invalid output\n");
|
||||
err = -EINVAL;
|
||||
goto free_all;
|
||||
@@ -1903,9 +1913,10 @@ static int do_test_rsa(struct crypto_akcipher *tfm,
|
||||
err = -ENOMEM;
|
||||
goto free_all;
|
||||
}
|
||||
sg_init_one(&src, vecs->c, vecs->c_size);
|
||||
sg_init_one(&dst, outbuf_dec, out_len_max);
|
||||
init_completion(&result.completion);
|
||||
akcipher_request_set_crypt(req, outbuf_enc, outbuf_dec, vecs->c_size,
|
||||
out_len);
|
||||
akcipher_request_set_crypt(req, &src, &dst, vecs->c_size, out_len_max);
|
||||
|
||||
/* Run RSA decrypt - m = c^d mod n;*/
|
||||
err = wait_async_op(&result, crypto_akcipher_decrypt(req));
|
||||
@@ -2080,7 +2091,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(md5),ecb(cipher_null))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2096,7 +2106,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),cbc(aes))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2110,7 +2119,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),cbc(des))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2124,7 +2132,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2138,7 +2145,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),ecb(cipher_null))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2158,7 +2164,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha224),cbc(des))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2172,7 +2177,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha224),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2186,7 +2190,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha256),cbc(aes))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2200,7 +2203,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha256),cbc(des))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2214,7 +2216,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha256),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2228,7 +2229,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha384),cbc(des))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2242,7 +2242,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha384),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2256,7 +2255,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha512),cbc(aes))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2270,7 +2268,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha512),cbc(des))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -2284,7 +2281,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha512),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = {
|
||||
.enc = {
|
||||
@@ -3011,7 +3007,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "ecb(des)",
|
||||
.test = alg_test_skcipher,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.cipher = {
|
||||
.enc = {
|
||||
@@ -3291,6 +3286,22 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "jitterentropy_rng",
|
||||
.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,
|
||||
|
||||
+68
-9
@@ -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];
|
||||
@@ -149,7 +150,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
||||
{
|
||||
#ifndef CONFIG_CRYPTO_FIPS
|
||||
.key =
|
||||
"\x30\x81\x88" /* sequence of 136 bytes */
|
||||
"\x30\x81\x9A" /* sequence of 154 bytes */
|
||||
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||
"\x02\x41" /* modulus - integer of 65 bytes */
|
||||
"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
|
||||
"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
|
||||
@@ -161,19 +163,25 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
||||
"\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
|
||||
"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
|
||||
"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
|
||||
"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51",
|
||||
"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"
|
||||
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||
.c =
|
||||
"\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63"
|
||||
"\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a"
|
||||
"\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53"
|
||||
"\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06",
|
||||
.key_len = 139,
|
||||
.key_len = 157,
|
||||
.m_size = 8,
|
||||
.c_size = 64,
|
||||
}, {
|
||||
.key =
|
||||
"\x30\x82\x01\x0B" /* sequence of 267 bytes */
|
||||
"\x30\x82\x01\x1D" /* sequence of 285 bytes */
|
||||
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||
"\x02\x81\x81" /* modulus - integer of 129 bytes */
|
||||
"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
|
||||
"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
|
||||
@@ -194,8 +202,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
||||
"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
|
||||
"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
|
||||
"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
|
||||
"\xC1",
|
||||
.key_len = 271,
|
||||
"\xC1"
|
||||
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||
.key_len = 289,
|
||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||
.c =
|
||||
"\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95"
|
||||
@@ -211,7 +224,8 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
||||
}, {
|
||||
#endif
|
||||
.key =
|
||||
"\x30\x82\x02\x0D" /* sequence of 525 bytes */
|
||||
"\x30\x82\x02\x1F" /* sequence of 543 bytes */
|
||||
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||
"\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
|
||||
"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
|
||||
"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
|
||||
@@ -246,8 +260,13 @@ static struct akcipher_testvec rsa_tv_template[] = {
|
||||
"\x77\xAF\x51\x27\x5B\x5E\x69\xB8\x81\xE6\x11\xC5\x43\x23\x81\x04"
|
||||
"\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82"
|
||||
"\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49"
|
||||
"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71",
|
||||
.key_len = 529,
|
||||
"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71"
|
||||
"\x02\x01\x00" /* prime1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* prime2 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||
.key_len = 547,
|
||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||
.c =
|
||||
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
|
||||
@@ -23813,6 +23832,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:
|
||||
|
||||
Reference in New Issue
Block a user