diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 22:36:57 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 22:36:57 +0100 |
| commit | 27d393e3d2a5dc873f563e143a3f20fd8fb9cdb2 (patch) | |
| tree | 851527b00f61ea18d64c296d580f42ec32938df8 /crypto | |
| parent | 7a822a9dd6e98ccec31f0f02bd4db6252ed7f188 (diff) | |
| parent | 5624ea54f3ba5c83d2e5503411a31a8be0278c1e (diff) | |
| download | linux-next-history-27d393e3d2a5dc873f563e143a3f20fd8fb9cdb2.tar.gz | |
Merge branch 'master' of https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 115 | ||||
| -rw-r--r-- | crypto/Makefile | 5 | ||||
| -rw-r--r-- | crypto/acompress.c | 8 | ||||
| -rw-r--r-- | crypto/aead.c | 10 | ||||
| -rw-r--r-- | crypto/af_alg.c | 106 | ||||
| -rw-r--r-- | crypto/ahash.c | 8 | ||||
| -rw-r--r-- | crypto/akcipher.c | 8 | ||||
| -rw-r--r-- | crypto/algif_aead.c | 51 | ||||
| -rw-r--r-- | crypto/algif_hash.c | 4 | ||||
| -rw-r--r-- | crypto/algif_rng.c | 4 | ||||
| -rw-r--r-- | crypto/algif_skcipher.c | 66 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/Kconfig | 1 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/verify_pefile.c | 2 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/x509_loader.c | 2 | ||||
| -rw-r--r-- | crypto/authencesn.c | 33 | ||||
| -rw-r--r-- | crypto/crypto_null.c | 35 | ||||
| -rw-r--r-- | crypto/crypto_user.c | 14 | ||||
| -rw-r--r-- | crypto/df_sp80090a.c | 8 | ||||
| -rw-r--r-- | crypto/drbg.c | 1771 | ||||
| -rw-r--r-- | crypto/ecc.c | 31 | ||||
| -rw-r--r-- | crypto/ecrdsa.c | 7 | ||||
| -rw-r--r-- | crypto/jitterentropy.c | 6 | ||||
| -rw-r--r-- | crypto/kpp.c | 8 | ||||
| -rw-r--r-- | crypto/krb5/krb5_api.c | 2 | ||||
| -rw-r--r-- | crypto/lskcipher.c | 10 | ||||
| -rw-r--r-- | crypto/rng.c | 8 | ||||
| -rw-r--r-- | crypto/scompress.c | 8 | ||||
| -rw-r--r-- | crypto/shash.c | 8 | ||||
| -rw-r--r-- | crypto/sig.c | 6 | ||||
| -rw-r--r-- | crypto/skcipher.c | 10 | ||||
| -rw-r--r-- | crypto/testmgr.c | 160 | ||||
| -rw-r--r-- | crypto/testmgr.h | 1076 |
32 files changed, 684 insertions, 2907 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 103d1f58cb7c2..b5c5a1e044353 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1113,44 +1113,16 @@ endmenu menu "Random number generation" -menuconfig CRYPTO_DRBG_MENU +config CRYPTO_DRBG tristate "NIST SP800-90A DRBG (Deterministic Random Bit Generator)" + select CRYPTO_JITTERENTROPY + select CRYPTO_LIB_SHA512 + select CRYPTO_RNG help DRBG (Deterministic Random Bit Generator) (NIST SP800-90A) - In the following submenu, one or more of the DRBG types must be selected. - -if CRYPTO_DRBG_MENU - -config CRYPTO_DRBG_HMAC - bool - default y - select CRYPTO_HMAC - select CRYPTO_SHA512 - -config CRYPTO_DRBG_HASH - bool "Hash_DRBG" - select CRYPTO_SHA256 - help - Hash_DRBG variant as defined in NIST SP800-90A. - - This uses the SHA-1, SHA-256, SHA-384, or SHA-512 hash algorithms. - -config CRYPTO_DRBG_CTR - bool "CTR_DRBG" - select CRYPTO_DF80090A - help - CTR_DRBG variant as defined in NIST SP800-90A. - - This uses the AES cipher algorithm with the counter block mode. - -config CRYPTO_DRBG - tristate - default CRYPTO_DRBG_MENU - select CRYPTO_RNG - select CRYPTO_JITTERENTROPY - -endif # if CRYPTO_DRBG_MENU + Enable this only if you need it for a FIPS 140 certification. + It's otherwise redundant with the kernel's regular RNG. config CRYPTO_JITTERENTROPY tristate "CPU Jitter Non-Deterministic RNG (Random Number Generator)" @@ -1280,44 +1252,68 @@ config CRYPTO_DF80090A select CRYPTO_CTR endmenu -menu "Userspace interface" +menu "Userspace interface (deprecated)" config CRYPTO_USER_API tristate config CRYPTO_USER_API_HASH - tristate "Hash algorithms" + tristate "Hash algorithms (deprecated)" depends on NET select CRYPTO_HASH select CRYPTO_USER_API help - Enable the userspace interface for hash algorithms. + Enable the AF_ALG userspace interface for hash algorithms. This + provides unprivileged userspace programs access to arbitrary hash + algorithms implemented in the kernel's privileged execution context. + + This interface is deprecated and is supported only for backwards + compatibility. It regularly has vulnerabilities, and the capabilities + it provides are redundant with userspace crypto libraries. + + Enable this only if needed for support for a program that hasn't yet + been converted to userspace crypto, for example iwd. - See Documentation/crypto/userspace-if.rst and - https://www.chronox.de/libkcapi/html/index.html + See also Documentation/crypto/userspace-if.rst config CRYPTO_USER_API_SKCIPHER - tristate "Symmetric key cipher algorithms" + tristate "Symmetric key cipher algorithms (deprecated)" depends on NET select CRYPTO_SKCIPHER select CRYPTO_USER_API help - Enable the userspace interface for symmetric key cipher algorithms. + Enable the AF_ALG userspace interface for symmetric key algorithms. + This provides unprivileged userspace programs access to arbitrary + symmetric key algorithms implemented in the kernel's privileged + execution context. - See Documentation/crypto/userspace-if.rst and - https://www.chronox.de/libkcapi/html/index.html + This interface is deprecated and is supported only for backwards + compatibility. It regularly has vulnerabilities, and the capabilities + it provides are redundant with userspace crypto libraries. + + Enable this only if needed for support for a program that hasn't yet + been converted to userspace crypto, for example iwd, or cryptsetup + with certain algorithms. + + See also Documentation/crypto/userspace-if.rst config CRYPTO_USER_API_RNG - tristate "RNG (random number generator) algorithms" + tristate "Random number generation algorithms (deprecated)" depends on NET select CRYPTO_RNG select CRYPTO_USER_API help - Enable the userspace interface for RNG (random number generator) - algorithms. + Enable the AF_ALG userspace interface for random number generation + (RNG) algorithms. This provides unprivileged userspace programs + access to arbitrary RNG algorithms implemented in the kernel's + privileged execution context. - See Documentation/crypto/userspace-if.rst and - https://www.chronox.de/libkcapi/html/index.html + This interface is deprecated and is supported only for backwards + compatibility. It regularly has vulnerabilities, and the capabilities + it provides are redundant with userspace crypto libraries as well as + the normal kernel RNG (e.g., /dev/urandom and getrandom(2)). + + See also Documentation/crypto/userspace-if.rst config CRYPTO_USER_API_RNG_CAVP bool "Enable CAVP testing of DRBG" @@ -1332,16 +1328,25 @@ config CRYPTO_USER_API_RNG_CAVP no unless you know what this is. config CRYPTO_USER_API_AEAD - tristate "AEAD cipher algorithms" + tristate "AEAD cipher algorithms (deprecated)" depends on NET select CRYPTO_AEAD select CRYPTO_SKCIPHER select CRYPTO_USER_API help - Enable the userspace interface for AEAD cipher algorithms. + Enable the AF_ALG userspace interface for authenticated encryption + with associated data (AEAD) algorithms. This provides unprivileged + userspace programs access to arbitrary AEAD algorithms implemented in + the kernel's privileged execution context. + + This interface is deprecated and is supported only for backwards + compatibility. It regularly has vulnerabilities, and the capabilities + it provides are redundant with userspace crypto libraries. - See Documentation/crypto/userspace-if.rst and - https://www.chronox.de/libkcapi/html/index.html + Enable this only if needed for support for a program that hasn't yet + been converted to userspace crypto, for example iwd. + + See also Documentation/crypto/userspace-if.rst config CRYPTO_USER_API_ENABLE_OBSOLETE bool "Obsolete cryptographic algorithms" @@ -1361,12 +1366,6 @@ endif if ARM64 source "arch/arm64/crypto/Kconfig" endif -if LOONGARCH -source "arch/loongarch/crypto/Kconfig" -endif -if MIPS -source "arch/mips/crypto/Kconfig" -endif if PPC source "arch/powerpc/crypto/Kconfig" endif diff --git a/crypto/Makefile b/crypto/Makefile index 162242593c7c1..c73f4d51d0368 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -178,6 +178,11 @@ obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o obj-$(CONFIG_CRYPTO_ECC) += ecc.o obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124949 +ifeq ($(CONFIG_ARM)$(CONFIG_KASAN_STACK)$(CONFIG_CC_IS_GCC),yyy) +CFLAGS_ecc.o += $(call cc-option,-Wframe-larger-than=1536) +endif + ecdh_generic-y += ecdh.o ecdh_generic-y += ecdh_helper.o obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o diff --git a/crypto/acompress.c b/crypto/acompress.c index 6025c1acce491..032de704eb2ca 100644 --- a/crypto/acompress.c +++ b/crypto/acompress.c @@ -51,11 +51,9 @@ static inline struct acomp_alg *crypto_acomp_alg(struct crypto_acomp *tfm) static int __maybe_unused crypto_acomp_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_acomp racomp; - - memset(&racomp, 0, sizeof(racomp)); - - strscpy(racomp.type, "acomp", sizeof(racomp.type)); + struct crypto_report_acomp racomp = { + .type = "acomp", + }; return nla_put(skb, CRYPTOCFGA_REPORT_ACOMP, sizeof(racomp), &racomp); } diff --git a/crypto/aead.c b/crypto/aead.c index e009937bf3a5d..045b74c3779f4 100644 --- a/crypto/aead.c +++ b/crypto/aead.c @@ -136,13 +136,11 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm) static int __maybe_unused crypto_aead_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_aead raead; struct aead_alg *aead = container_of(alg, struct aead_alg, base); - - memset(&raead, 0, sizeof(raead)); - - strscpy(raead.type, "aead", sizeof(raead.type)); - strscpy(raead.geniv, "<none>", sizeof(raead.geniv)); + struct crypto_report_aead raead = { + .type = "aead", + .geniv = "<none>", + }; raead.blocksize = alg->cra_blocksize; raead.maxauthsize = aead->maxauthsize; diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 5a00c18eb145c..cce000e8590e4 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -181,7 +181,7 @@ static int alg_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int add if (IS_ERR(type)) return PTR_ERR(type); - private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask); + private = type->bind(sa->salg_name); if (IS_ERR(private)) { module_put(type->owner); return PTR_ERR(private); @@ -584,6 +584,8 @@ static int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32))) return -EINVAL; con->aead_assoclen = *(u32 *)CMSG_DATA(cmsg); + if (con->aead_assoclen >= 0x80000000u) + return -EINVAL; break; default: @@ -973,7 +975,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, ssize_t plen; /* use the existing memory in an allocated page */ - if (ctx->merge && !(msg->msg_flags & MSG_SPLICE_PAGES)) { + if (ctx->merge) { sgl = list_entry(ctx->tsgl_list.prev, struct af_alg_tsgl, list); sg = sgl->sg + sgl->cur - 1; @@ -1017,60 +1019,37 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, if (sgl->cur) sg_unmark_end(sg + sgl->cur - 1); - if (msg->msg_flags & MSG_SPLICE_PAGES) { - struct sg_table sgtable = { - .sgl = sg, - .nents = sgl->cur, - .orig_nents = sgl->cur, - }; + do { + struct page *pg; + unsigned int i = sgl->cur; + + plen = min_t(size_t, len, PAGE_SIZE); + + pg = alloc_page(GFP_KERNEL); + if (!pg) { + err = -ENOMEM; + goto unlock; + } + + sg_assign_page(sg + i, pg); - plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable, - MAX_SGL_ENTS - sgl->cur, 0); - if (plen < 0) { - err = plen; + err = memcpy_from_msg(page_address(sg_page(sg + i)), + msg, plen); + if (err) { + __free_page(sg_page(sg + i)); + sg_assign_page(sg + i, NULL); goto unlock; } - for (; sgl->cur < sgtable.nents; sgl->cur++) - get_page(sg_page(&sg[sgl->cur])); + sg[i].length = plen; len -= plen; ctx->used += plen; copied += plen; size -= plen; - } else { - do { - struct page *pg; - unsigned int i = sgl->cur; - - plen = min_t(size_t, len, PAGE_SIZE); - - pg = alloc_page(GFP_KERNEL); - if (!pg) { - err = -ENOMEM; - goto unlock; - } - - sg_assign_page(sg + i, pg); - - err = memcpy_from_msg( - page_address(sg_page(sg + i)), - msg, plen); - if (err) { - __free_page(sg_page(sg + i)); - sg_assign_page(sg + i, NULL); - goto unlock; - } - - sg[i].length = plen; - len -= plen; - ctx->used += plen; - copied += plen; - size -= plen; - sgl->cur++; - } while (len && sgl->cur < MAX_SGL_ENTS); + sgl->cur++; + } while (len && sgl->cur < MAX_SGL_ENTS); - ctx->merge = plen & (PAGE_SIZE - 1); - } + ctx->merge = plen & (PAGE_SIZE - 1); if (!size) sg_mark_end(sg + sgl->cur - 1); @@ -1107,35 +1086,6 @@ void af_alg_free_resources(struct af_alg_async_req *areq) EXPORT_SYMBOL_GPL(af_alg_free_resources); /** - * af_alg_async_cb - AIO callback handler - * @data: async request completion data - * @err: if non-zero, error result to be returned via ki_complete(); - * otherwise return the AIO output length via ki_complete(). - * - * This handler cleans up the struct af_alg_async_req upon completion of the - * AIO operation. - * - * The number of bytes to be generated with the AIO operation must be set - * in areq->outlen before the AIO callback handler is invoked. - */ -void af_alg_async_cb(void *data, int err) -{ - struct af_alg_async_req *areq = data; - struct sock *sk = areq->sk; - struct kiocb *iocb = areq->iocb; - unsigned int resultlen; - - /* Buffer size written by crypto operation. */ - resultlen = areq->outlen; - - af_alg_free_resources(areq); - sock_put(sk); - - iocb->ki_complete(iocb, err ? err : (int)resultlen); -} -EXPORT_SYMBOL_GPL(af_alg_async_cb); - -/** * af_alg_poll - poll system call handler * @file: file pointer * @sock: socket to poll @@ -1175,8 +1125,8 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, struct af_alg_ctx *ctx = alg_sk(sk)->private; struct af_alg_async_req *areq; - /* Only one AIO request can be in flight. */ - if (ctx->inflight) + /* Only one request can be in flight. */ + if (WARN_ON_ONCE(ctx->inflight)) return ERR_PTR(-EBUSY); areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); diff --git a/crypto/ahash.c b/crypto/ahash.c index 85dcd120de3ee..d86c78f8d5501 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -789,11 +789,9 @@ static void crypto_ahash_free_instance(struct crypto_instance *inst) static int __maybe_unused crypto_ahash_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_hash rhash; - - memset(&rhash, 0, sizeof(rhash)); - - strscpy(rhash.type, "ahash", sizeof(rhash.type)); + struct crypto_report_hash rhash = { + .type = "ahash", + }; rhash.blocksize = alg->cra_blocksize; rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize; diff --git a/crypto/akcipher.c b/crypto/akcipher.c index dfe87b3ce1837..630bb19738beb 100644 --- a/crypto/akcipher.c +++ b/crypto/akcipher.c @@ -36,11 +36,9 @@ struct crypto_akcipher_sync_data { static int __maybe_unused crypto_akcipher_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_akcipher rakcipher; - - memset(&rakcipher, 0, sizeof(rakcipher)); - - strscpy(rakcipher.type, "akcipher", sizeof(rakcipher.type)); + struct crypto_report_akcipher rakcipher = { + .type = "akcipher", + }; return nla_put(skb, CRYPTOCFGA_REPORT_AKCIPHER, sizeof(rakcipher), &rakcipher); diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index cb651ab58d629..787aac8aeb24e 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -9,10 +9,10 @@ * The following concept of the memory management is used: * * The kernel maintains two SGLs, the TX SGL and the RX SGL. The TX SGL is - * filled by user space with the data submitted via sendmsg (maybe with - * MSG_SPLICE_PAGES). Filling up the TX SGL does not cause a crypto operation - * -- the data will only be tracked by the kernel. Upon receipt of one recvmsg - * call, the caller must provide a buffer which is tracked with the RX SGL. + * filled by user space with the data submitted via sendmsg. Filling up the TX + * SGL does not cause a crypto operation -- the data will only be tracked by the + * kernel. Upon receipt of one recvmsg call, the caller must provide a buffer + * which is tracked with the RX SGL. * * During the processing of the recvmsg operation, the cipher request is * allocated and prepared. As part of the recvmsg operation, the processed @@ -197,37 +197,14 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg, aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen); aead_request_set_tfm(&areq->cra_u.aead_req, tfm); - if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) { - /* AIO operation */ - sock_hold(sk); - areq->iocb = msg->msg_iocb; - - /* Remember output size that will be generated. */ - areq->outlen = outlen; - - aead_request_set_callback(&areq->cra_u.aead_req, - CRYPTO_TFM_REQ_MAY_SLEEP, - af_alg_async_cb, areq); - err = ctx->enc ? crypto_aead_encrypt(&areq->cra_u.aead_req) : - crypto_aead_decrypt(&areq->cra_u.aead_req); - - /* AIO operation in progress */ - if (err == -EINPROGRESS) - return -EIOCBQUEUED; - - sock_put(sk); - } else { - /* Synchronous operation */ - aead_request_set_callback(&areq->cra_u.aead_req, - CRYPTO_TFM_REQ_MAY_SLEEP | - CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &ctx->wait); - err = crypto_wait_req(ctx->enc ? - crypto_aead_encrypt(&areq->cra_u.aead_req) : - crypto_aead_decrypt(&areq->cra_u.aead_req), - &ctx->wait); - } - + aead_request_set_callback(&areq->cra_u.aead_req, + CRYPTO_TFM_REQ_MAY_SLEEP | + CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &ctx->wait); + err = crypto_wait_req(ctx->enc ? + crypto_aead_encrypt(&areq->cra_u.aead_req) : + crypto_aead_decrypt(&areq->cra_u.aead_req), + &ctx->wait); free: af_alg_free_resources(areq); @@ -365,9 +342,9 @@ static struct proto_ops algif_aead_ops_nokey = { .poll = af_alg_poll, }; -static void *aead_bind(const char *name, u32 type, u32 mask) +static void *aead_bind(const char *name) { - return crypto_alloc_aead(name, type, mask); + return crypto_alloc_aead(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void aead_release(void *private) diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 4d3dfc60a16a6..5452ad6c15069 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -380,9 +380,9 @@ static struct proto_ops algif_hash_ops_nokey = { .accept = hash_accept_nokey, }; -static void *hash_bind(const char *name, u32 type, u32 mask) +static void *hash_bind(const char *name) { - return crypto_alloc_ahash(name, type, mask); + return crypto_alloc_ahash(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void hash_release(void *private) diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index a9fb492e929a7..4dfe7899f8fa4 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -197,7 +197,7 @@ static struct proto_ops __maybe_unused algif_rng_test_ops = { .sendmsg = rng_test_sendmsg, }; -static void *rng_bind(const char *name, u32 type, u32 mask) +static void *rng_bind(const char *name) { struct rng_parent_ctx *pctx; struct crypto_rng *rng; @@ -206,7 +206,7 @@ static void *rng_bind(const char *name, u32 type, u32 mask) if (!pctx) return ERR_PTR(-ENOMEM); - rng = crypto_alloc_rng(name, type, mask); + rng = crypto_alloc_rng(name, 0, AF_ALG_CRYPTOAPI_MASK); if (IS_ERR(rng)) { kfree(pctx); return ERR_CAST(rng); diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index ba0a17fd95aca..df20bdfe1f1f4 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -79,20 +79,6 @@ static int algif_skcipher_export(struct sock *sk, struct skcipher_request *req) return err; } -static void algif_skcipher_done(void *data, int err) -{ - struct af_alg_async_req *areq = data; - struct sock *sk = areq->sk; - - if (err) - goto out; - - err = algif_skcipher_export(sk, &areq->cra_u.skcipher_req); - -out: - af_alg_async_cb(data, err); -} - static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, size_t ignored, int flags) { @@ -171,43 +157,19 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, cflags |= CRYPTO_SKCIPHER_REQ_CONT; } - if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) { - /* AIO operation */ - sock_hold(sk); - areq->iocb = msg->msg_iocb; - - /* Remember output size that will be generated. */ - areq->outlen = len; - - skcipher_request_set_callback(&areq->cra_u.skcipher_req, - cflags | - CRYPTO_TFM_REQ_MAY_SLEEP, - algif_skcipher_done, areq); - err = ctx->enc ? - crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : - crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); + skcipher_request_set_callback(&areq->cra_u.skcipher_req, + cflags | + CRYPTO_TFM_REQ_MAY_SLEEP | + CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &ctx->wait); + err = crypto_wait_req(ctx->enc ? + crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : + crypto_skcipher_decrypt(&areq->cra_u.skcipher_req), + &ctx->wait); - /* AIO operation in progress */ - if (err == -EINPROGRESS) - return -EIOCBQUEUED; - - sock_put(sk); - } else { - /* Synchronous operation */ - skcipher_request_set_callback(&areq->cra_u.skcipher_req, - cflags | - CRYPTO_TFM_REQ_MAY_SLEEP | - CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &ctx->wait); - err = crypto_wait_req(ctx->enc ? - crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : - crypto_skcipher_decrypt(&areq->cra_u.skcipher_req), - &ctx->wait); - - if (!err) - err = algif_skcipher_export( - sk, &areq->cra_u.skcipher_req); - } + if (!err) + err = algif_skcipher_export( + sk, &areq->cra_u.skcipher_req); free: af_alg_free_resources(areq); @@ -345,9 +307,9 @@ static struct proto_ops algif_skcipher_ops_nokey = { .poll = af_alg_poll, }; -static void *skcipher_bind(const char *name, u32 type, u32 mask) +static void *skcipher_bind(const char *name) { - return crypto_alloc_skcipher(name, type, mask); + return crypto_alloc_skcipher(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void skcipher_release(void *private) diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index e50bd9b3e27ba..6a2f664046efe 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -95,7 +95,6 @@ config FIPS_SIGNATURE_SELFTEST verification code, using some built in data. This is required for FIPS. depends on KEYS - depends on ASYMMETRIC_KEY_TYPE depends on PKCS7_MESSAGE_PARSER=X509_CERTIFICATE_PARSER depends on X509_CERTIFICATE_PARSER depends on CRYPTO_RSA diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 1f3b227ba7f22..cec99db14129a 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -305,6 +305,8 @@ static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen, if (pelen > hashed_bytes) { tmp = hashed_bytes + ctx->certs_size; + if (tmp <= hashed_bytes || pelen < tmp) + return -ELIBBAD; ret = crypto_shash_update(desc, pebuf + hashed_bytes, pelen - tmp); diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c index a417413269989..0d516c77cc26a 100644 --- a/crypto/asymmetric_keys/x509_loader.c +++ b/crypto/asymmetric_keys/x509_loader.c @@ -20,7 +20,7 @@ int x509_load_certificate_list(const u8 cert_list[], */ if (end - p < 4) goto dodgy_cert; - if (p[0] != 0x30 && + if (p[0] != 0x30 || p[1] != 0x82) goto dodgy_cert; plen = (p[2] << 8) | p[3]; diff --git a/crypto/authencesn.c b/crypto/authencesn.c index 522df41365d8f..ca063576f6706 100644 --- a/crypto/authencesn.c +++ b/crypto/authencesn.c @@ -94,11 +94,11 @@ static int crypto_authenc_esn_genicv_tail(struct aead_request *req, u32 tmp[2]; /* Move high-order bits of sequence number back. */ - scatterwalk_map_and_copy(tmp, dst, 4, 4, 0); - scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0); - scatterwalk_map_and_copy(tmp, dst, 0, 8, 1); + memcpy_from_sglist(tmp, dst, 4, 4); + memcpy_from_sglist(tmp + 1, dst, assoclen + cryptlen, 4); + memcpy_to_sglist(dst, 0, tmp, 8); - scatterwalk_map_and_copy(hash, dst, assoclen + cryptlen, authsize, 1); + memcpy_to_sglist(dst, assoclen + cryptlen, hash, authsize); return 0; } @@ -129,9 +129,9 @@ static int crypto_authenc_esn_genicv(struct aead_request *req, return 0; /* Move high-order bits of sequence number to the end. */ - scatterwalk_map_and_copy(tmp, dst, 0, 8, 0); - scatterwalk_map_and_copy(tmp, dst, 4, 4, 1); - scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1); + memcpy_from_sglist(tmp, dst, 0, 8); + memcpy_to_sglist(dst, 4, tmp, 4); + memcpy_to_sglist(dst, assoclen + cryptlen, tmp + 1, 4); sg_init_table(areq_ctx->dst, 2); dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4); @@ -217,9 +217,9 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req, if (src == dst) { /* Move high-order bits of sequence number back. */ - scatterwalk_map_and_copy(tmp, dst, 4, 4, 0); - scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 0); - scatterwalk_map_and_copy(tmp, dst, 0, 8, 1); + memcpy_from_sglist(tmp, dst, 4, 4); + memcpy_from_sglist(tmp + 1, dst, assoclen + cryptlen, 4); + memcpy_to_sglist(dst, 0, tmp, 8); } else memcpy_sglist(dst, src, assoclen); @@ -274,18 +274,17 @@ static int crypto_authenc_esn_decrypt(struct aead_request *req) goto tail; cryptlen -= authsize; - scatterwalk_map_and_copy(ihash, req->src, assoclen + cryptlen, - authsize, 0); + memcpy_from_sglist(ihash, req->src, assoclen + cryptlen, authsize); /* Move high-order bits of sequence number to the end. */ - scatterwalk_map_and_copy(tmp, src, 0, 8, 0); + memcpy_from_sglist(tmp, src, 0, 8); if (src == dst) { - scatterwalk_map_and_copy(tmp, dst, 4, 4, 1); - scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1); + memcpy_to_sglist(dst, 4, tmp, 4); + memcpy_to_sglist(dst, assoclen + cryptlen, tmp + 1, 4); dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4); } else { - scatterwalk_map_and_copy(tmp, dst, 0, 4, 1); - scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen - 4, 4, 1); + memcpy_to_sglist(dst, 0, tmp, 4); + memcpy_to_sglist(dst, assoclen + cryptlen - 4, tmp + 1, 4); src = scatterwalk_ffwd(areq_ctx->src, src, 8); dst = scatterwalk_ffwd(areq_ctx->dst, dst, 4); diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c index 34588f39fdfc6..fea151df1648a 100644 --- a/crypto/crypto_null.c +++ b/crypto/crypto_null.c @@ -50,15 +50,6 @@ static int null_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) { return 0; } -static int null_setkey(struct crypto_tfm *tfm, const u8 *key, - unsigned int keylen) -{ return 0; } - -static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) -{ - memcpy(dst, src, NULL_BLOCK_SIZE); -} - static int null_skcipher_crypt(struct skcipher_request *req) { if (req->src != req->dst) @@ -97,35 +88,16 @@ static struct skcipher_alg skcipher_null = { .decrypt = null_skcipher_crypt, }; -static struct crypto_alg cipher_null = { - .cra_name = "cipher_null", - .cra_driver_name = "cipher_null-generic", - .cra_flags = CRYPTO_ALG_TYPE_CIPHER, - .cra_blocksize = NULL_BLOCK_SIZE, - .cra_ctxsize = 0, - .cra_module = THIS_MODULE, - .cra_u = { .cipher = { - .cia_min_keysize = NULL_KEY_SIZE, - .cia_max_keysize = NULL_KEY_SIZE, - .cia_setkey = null_setkey, - .cia_encrypt = null_crypt, - .cia_decrypt = null_crypt } } -}; - MODULE_ALIAS_CRYPTO("digest_null"); -MODULE_ALIAS_CRYPTO("cipher_null"); +MODULE_ALIAS_CRYPTO("ecb(cipher_null)"); static int __init crypto_null_mod_init(void) { int ret = 0; - ret = crypto_register_alg(&cipher_null); - if (ret < 0) - goto out; - ret = crypto_register_shash(&digest_null); if (ret < 0) - goto out_unregister_algs; + goto out; ret = crypto_register_skcipher(&skcipher_null); if (ret < 0) @@ -135,15 +107,12 @@ static int __init crypto_null_mod_init(void) out_unregister_shash: crypto_unregister_shash(&digest_null); -out_unregister_algs: - crypto_unregister_alg(&cipher_null); out: return ret; } static void __exit crypto_null_mod_fini(void) { - crypto_unregister_alg(&cipher_null); crypto_unregister_shash(&digest_null); crypto_unregister_skcipher(&skcipher_null); } diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 3187e0d276f90..e8b6ae75f31f7 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -70,11 +70,9 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_cipher rcipher; - - memset(&rcipher, 0, sizeof(rcipher)); - - strscpy(rcipher.type, "cipher", sizeof(rcipher.type)); + struct crypto_report_cipher rcipher = { + .type = "cipher", + }; rcipher.blocksize = alg->cra_blocksize; rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; @@ -103,10 +101,10 @@ static int crypto_report_one(struct crypto_alg *alg, if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority)) goto nla_put_failure; if (alg->cra_flags & CRYPTO_ALG_LARVAL) { - struct crypto_report_larval rl; + struct crypto_report_larval rl = { + .type = "larval", + }; - memset(&rl, 0, sizeof(rl)); - strscpy(rl.type, "larval", sizeof(rl.type)); if (nla_put(skb, CRYPTOCFGA_REPORT_LARVAL, sizeof(rl), &rl)) goto nla_put_failure; goto out; diff --git a/crypto/df_sp80090a.c b/crypto/df_sp80090a.c index b8134be6f7ad9..90e1973ee40c7 100644 --- a/crypto/df_sp80090a.c +++ b/crypto/df_sp80090a.c @@ -10,9 +10,9 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/string.h> +#include <linux/unaligned.h> #include <crypto/aes.h> #include <crypto/df_sp80090a.h> -#include <crypto/internal/drbg.h> static void drbg_kcapi_sym(struct aes_enckey *aeskey, unsigned char *outval, const struct drbg_string *in, u8 blocklen_bytes) @@ -141,10 +141,10 @@ int crypto_drbg_ctr_df(struct aes_enckey *aeskey, /* 10.4.2 step 2 -- calculate the entire length of all input data */ list_for_each_entry(seed, seedlist, list) inputlen += seed->len; - drbg_cpu_to_be32(inputlen, &L_N[0]); + put_unaligned_be32(inputlen, &L_N[0]); /* 10.4.2 step 3 */ - drbg_cpu_to_be32(bytes_to_return, &L_N[4]); + put_unaligned_be32(bytes_to_return, &L_N[4]); /* 10.4.2 step 5: length is L_N, input_string, one byte, padding */ padlen = (inputlen + sizeof(L_N) + 1) % (blocklen_bytes); @@ -175,7 +175,7 @@ int crypto_drbg_ctr_df(struct aes_enckey *aeskey, * holds zeros after allocation -- even the increment of i * is irrelevant as the increment remains within length of i */ - drbg_cpu_to_be32(i, iv); + put_unaligned_be32(i, iv); /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ drbg_ctr_bcc(aeskey, temp + templen, K, &bcc_list, blocklen_bytes, keylen); diff --git a/crypto/drbg.c b/crypto/drbg.c index 9204e6edb4268..d66c7211d6bb0 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1,13 +1,9 @@ /* * DRBG: Deterministic Random Bits Generator - * Based on NIST Recommended DRBG from NIST SP800-90A with the following - * properties: - * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores - * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores - * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores - * * with and without prediction resistance + * Implementation of the HMAC SHA-512 DRBG from NIST SP800-90A * * Copyright Stephan Mueller <smueller@chronox.de>, 2014 + * Copyright 2026 Google LLC * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -55,7 +51,7 @@ * char data[DATALEN]; * * drng = crypto_alloc_rng(drng_name, 0, 0); - * err = crypto_rng_get_bytes(drng, &data, DATALEN); + * err = crypto_rng_get_bytes(drng, data, DATALEN); * crypto_free_rng(drng); * * @@ -64,15 +60,13 @@ * struct crypto_rng *drng; * int err; * char data[DATALEN]; - * struct drbg_string pers; * char personalization[11] = "some-string"; * - * drbg_string_fill(&pers, personalization, strlen(personalization)); * drng = crypto_alloc_rng(drng_name, 0, 0); * // The reset completely re-initializes the DRBG with the provided * // personalization string - * err = crypto_rng_reset(drng, &personalization, strlen(personalization)); - * err = crypto_rng_get_bytes(drng, &data, DATALEN); + * err = crypto_rng_reset(drng, personalization, strlen(personalization)); + * err = crypto_rng_get_bytes(drng, data, DATALEN); * crypto_free_rng(drng); * * @@ -82,13 +76,10 @@ * int err; * char data[DATALEN]; * char addtl_string[11] = "some-string"; - * string drbg_string addtl; * - * drbg_string_fill(&addtl, addtl_string, strlen(addtl_string)); * drng = crypto_alloc_rng(drng_name, 0, 0); - * // The following call is a wrapper to crypto_rng_get_bytes() and returns - * // the same error codes. - * err = crypto_drbg_get_bytes_addtl(drng, &data, DATALEN, &addtl); + * err = crypto_rng_generate(drng, addtl_string, strlen(addtl_string), + data, DATALEN); * crypto_free_rng(drng); * * @@ -97,803 +88,129 @@ * Just mix both scenarios above. */ -#include <crypto/drbg.h> -#include <crypto/df_sp80090a.h> -#include <crypto/internal/cipher.h> +#include <crypto/internal/rng.h> +#include <crypto/sha2.h> +#include <linux/fips.h> #include <linux/kernel.h> -#include <linux/jiffies.h> +#include <linux/module.h> +#include <linux/mutex.h> #include <linux/string_choices.h> +#include <linux/unaligned.h> -/*************************************************************** - * Backend cipher definitions available to DRBG - ***************************************************************/ - -/* - * The order of the DRBG definitions here matter: every DRBG is registered - * as stdrng. Each DRBG receives an increasing cra_priority values the later - * they are defined in this array (see drbg_fill_array). - * - * HMAC DRBGs are favored over Hash DRBGs over CTR DRBGs, and the - * HMAC-SHA512 / SHA256 / AES 256 over other ciphers. Thus, the - * favored DRBGs are the latest entries in this array. - */ -static const struct drbg_core drbg_cores[] = { -#ifdef CONFIG_CRYPTO_DRBG_CTR - { - .flags = DRBG_CTR | DRBG_STRENGTH128, - .statelen = 32, /* 256 bits as defined in 10.2.1 */ - .blocklen_bytes = 16, - .cra_name = "ctr_aes128", - .backend_cra_name = "aes", - }, { - .flags = DRBG_CTR | DRBG_STRENGTH192, - .statelen = 40, /* 320 bits as defined in 10.2.1 */ - .blocklen_bytes = 16, - .cra_name = "ctr_aes192", - .backend_cra_name = "aes", - }, { - .flags = DRBG_CTR | DRBG_STRENGTH256, - .statelen = 48, /* 384 bits as defined in 10.2.1 */ - .blocklen_bytes = 16, - .cra_name = "ctr_aes256", - .backend_cra_name = "aes", - }, -#endif /* CONFIG_CRYPTO_DRBG_CTR */ -#ifdef CONFIG_CRYPTO_DRBG_HASH - { - .flags = DRBG_HASH | DRBG_STRENGTH256, - .statelen = 111, /* 888 bits */ - .blocklen_bytes = 48, - .cra_name = "sha384", - .backend_cra_name = "sha384", - }, { - .flags = DRBG_HASH | DRBG_STRENGTH256, - .statelen = 111, /* 888 bits */ - .blocklen_bytes = 64, - .cra_name = "sha512", - .backend_cra_name = "sha512", - }, { - .flags = DRBG_HASH | DRBG_STRENGTH256, - .statelen = 55, /* 440 bits */ - .blocklen_bytes = 32, - .cra_name = "sha256", - .backend_cra_name = "sha256", - }, -#endif /* CONFIG_CRYPTO_DRBG_HASH */ -#ifdef CONFIG_CRYPTO_DRBG_HMAC - { - .flags = DRBG_HMAC | DRBG_STRENGTH256, - .statelen = 48, /* block length of cipher */ - .blocklen_bytes = 48, - .cra_name = "hmac_sha384", - .backend_cra_name = "hmac(sha384)", - }, { - .flags = DRBG_HMAC | DRBG_STRENGTH256, - .statelen = 32, /* block length of cipher */ - .blocklen_bytes = 32, - .cra_name = "hmac_sha256", - .backend_cra_name = "hmac(sha256)", - }, { - .flags = DRBG_HMAC | DRBG_STRENGTH256, - .statelen = 64, /* block length of cipher */ - .blocklen_bytes = 64, - .cra_name = "hmac_sha512", - .backend_cra_name = "hmac(sha512)", - }, -#endif /* CONFIG_CRYPTO_DRBG_HMAC */ -}; +/* State length in bytes */ +#define DRBG_STATE_LEN SHA512_DIGEST_SIZE -static int drbg_uninstantiate(struct drbg_state *drbg); - -/****************************************************************** - * Generic helper functions - ******************************************************************/ +/* Security strength in bytes */ +#define DRBG_SEC_STRENGTH (SHA512_DIGEST_SIZE / 2) /* - * Return strength of DRBG according to SP800-90A section 8.4 - * - * @flags DRBG flags reference - * - * Return: normalized strength in *bytes* value or 32 as default - * to counter programming errors + * Maximum number of requests before reseeding is forced. + * SP800-90A allows this to be up to 2**48. We use a lower value. */ -static inline unsigned short drbg_sec_strength(drbg_flag_t flags) -{ - switch (flags & DRBG_STRENGTH_MASK) { - case DRBG_STRENGTH128: - return 16; - case DRBG_STRENGTH192: - return 24; - case DRBG_STRENGTH256: - return 32; - default: - return 32; - } -} +#define DRBG_MAX_REQUESTS 4096 /* - * FIPS 140-2 continuous self test for the noise source - * The test is performed on the noise source input data. Thus, the function - * implicitly knows the size of the buffer to be equal to the security - * strength. - * - * Note, this function disregards the nonce trailing the entropy data during - * initial seeding. - * - * drbg->drbg_mutex must have been taken. - * - * @drbg DRBG handle - * @entropy buffer of seed data to be checked - * - * return: - * %true on success - * %false when the CTRNG is not yet primed + * Maximum number of random bytes that can be requested at once. + * SP800-90A allows up to 2**19 bits, which is 2**16 bytes. */ -static bool drbg_fips_continuous_test(struct drbg_state *drbg, - const unsigned char *entropy) - __must_hold(&drbg->drbg_mutex) -{ - unsigned short entropylen = drbg_sec_strength(drbg->core->flags); - - if (!IS_ENABLED(CONFIG_CRYPTO_FIPS)) - return true; - - /* skip test if we test the overall system */ - if (list_empty(&drbg->test_data.list)) - return true; - /* only perform test in FIPS mode */ - if (!fips_enabled) - return true; - - if (!drbg->fips_primed) { - /* Priming of FIPS test */ - memcpy(drbg->prev, entropy, entropylen); - drbg->fips_primed = true; - /* priming: another round is needed */ - return false; - } - if (!memcmp(drbg->prev, entropy, entropylen)) - panic("DRBG continuous self test failed\n"); - memcpy(drbg->prev, entropy, entropylen); - - /* the test shall pass when the two values are not equal */ - return true; -} - -/****************************************************************** - * CTR DRBG callback functions - ******************************************************************/ - -#ifdef CONFIG_CRYPTO_DRBG_CTR -#define CRYPTO_DRBG_CTR_STRING "CTR " -MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes256"); -MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes256"); -MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes192"); -MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes192"); -MODULE_ALIAS_CRYPTO("drbg_pr_ctr_aes128"); -MODULE_ALIAS_CRYPTO("drbg_nopr_ctr_aes128"); - -static int drbg_init_sym_kernel(struct drbg_state *drbg); -static int drbg_fini_sym_kernel(struct drbg_state *drbg); -static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, - u8 *inbuf, u32 inbuflen, - u8 *outbuf, u32 outlen); -#define DRBG_OUTSCRATCHLEN 256 - -static int drbg_ctr_df(struct drbg_state *drbg, - unsigned char *df_data, size_t bytes_to_return, - struct list_head *seedlist) -{ - return crypto_drbg_ctr_df(drbg->priv_data, df_data, drbg_statelen(drbg), - seedlist, drbg_blocklen(drbg), drbg_statelen(drbg)); -} +#define DRBG_MAX_REQUEST_BYTES (1 << 16) /* - * update function of CTR DRBG as defined in 10.2.1.2 - * - * The reseed variable has an enhanced meaning compared to the update - * functions of the other DRBGs as follows: - * 0 => initial seed from initialization - * 1 => reseed via drbg_seed - * 2 => first invocation from drbg_ctr_update when addtl is present. In - * this case, the df_data scratchpad is not deleted so that it is - * available for another calls to prevent calling the DF function - * again. - * 3 => second invocation from drbg_ctr_update. When the update function - * was called with addtl, the df_data memory already contains the - * DFed addtl information and we do not need to call DF again. + * Maximum length of additional info and personalization strings, in bytes. + * SP800-90A allows up to 2**35 bits, i.e. 2**32 bytes. We use 2**32 - 2 bytes + * so that the value never quite completely fills the range of a size_t, + * allowing the health check to verify that larger values are rejected. */ -static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, - int reseed) -{ - int ret = -EFAULT; - /* 10.2.1.2 step 1 */ - unsigned char *temp = drbg->scratchpad; - unsigned char *df_data = drbg->scratchpad + drbg_statelen(drbg) + - drbg_blocklen(drbg); +#define DRBG_MAX_ADDTL_BYTES (U32_MAX - 1) - if (3 > reseed) - memset(df_data, 0, drbg_statelen(drbg)); - - if (!reseed) { - /* - * The DRBG uses the CTR mode of the underlying AES cipher. The - * CTR mode increments the counter value after the AES operation - * but SP800-90A requires that the counter is incremented before - * the AES operation. Hence, we increment it at the time we set - * it by one. - */ - crypto_inc(drbg->V, drbg_blocklen(drbg)); - - ret = crypto_skcipher_setkey(drbg->ctr_handle, drbg->C, - drbg_keylen(drbg)); - if (ret) - goto out; - } - - /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ - if (seed) { - ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed); - if (ret) - goto out; - } - - ret = drbg_kcapi_sym_ctr(drbg, df_data, drbg_statelen(drbg), - temp, drbg_statelen(drbg)); - if (ret) - return ret; - - /* 10.2.1.2 step 5 */ - ret = crypto_skcipher_setkey(drbg->ctr_handle, temp, - drbg_keylen(drbg)); - if (ret) - goto out; - /* 10.2.1.2 step 6 */ - memcpy(drbg->V, temp + drbg_keylen(drbg), drbg_blocklen(drbg)); - /* See above: increment counter by one to compensate timing of CTR op */ - crypto_inc(drbg->V, drbg_blocklen(drbg)); - ret = 0; - -out: - memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); - if (2 != reseed) - memset(df_data, 0, drbg_statelen(drbg)); - return ret; -} - -/* - * scratchpad use: drbg_ctr_update is called independently from - * drbg_ctr_extract_bytes. Therefore, the scratchpad is reused - */ -/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ -static int drbg_ctr_generate(struct drbg_state *drbg, - unsigned char *buf, unsigned int buflen, - struct list_head *addtl) -{ - int ret; - int len = min_t(int, buflen, INT_MAX); - - /* 10.2.1.5.2 step 2 */ - if (addtl && !list_empty(addtl)) { - ret = drbg_ctr_update(drbg, addtl, 2); - if (ret) - return 0; - } - - /* 10.2.1.5.2 step 4.1 */ - ret = drbg_kcapi_sym_ctr(drbg, NULL, 0, buf, len); - if (ret) - return ret; - - /* 10.2.1.5.2 step 6 */ - ret = drbg_ctr_update(drbg, NULL, 3); - if (ret) - len = ret; - - return len; -} - -static const struct drbg_state_ops drbg_ctr_ops = { - .update = drbg_ctr_update, - .generate = drbg_ctr_generate, - .crypto_init = drbg_init_sym_kernel, - .crypto_fini = drbg_fini_sym_kernel, +struct drbg_state { + struct mutex drbg_mutex; /* lock around DRBG */ + u8 V[DRBG_STATE_LEN]; /* internal state -- 10.1.2.1 1a */ + struct hmac_sha512_key key; /* current key -- 10.1.2.1 1b */ + /* Number of RNG requests since last reseed -- 10.1.2.1 1c */ + size_t reseed_ctr; + bool instantiated; + struct crypto_rng *jent; + const u8 *test_entropy; + size_t test_entropylen; }; -#endif /* CONFIG_CRYPTO_DRBG_CTR */ /****************************************************************** - * HMAC DRBG callback functions + * HMAC DRBG functions ******************************************************************/ -#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC) -static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval, - const struct list_head *in); -static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg, - const unsigned char *key); -static int drbg_init_hash_kernel(struct drbg_state *drbg); -static int drbg_fini_hash_kernel(struct drbg_state *drbg); -#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ - -#ifdef CONFIG_CRYPTO_DRBG_HMAC -#define CRYPTO_DRBG_HMAC_STRING "HMAC " -MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha512"); -MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512"); -MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha384"); -MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha384"); -MODULE_ALIAS_CRYPTO("drbg_pr_hmac_sha256"); -MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha256"); - /* update function of HMAC DRBG as defined in 10.1.2.2 */ -static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed, - int reseed) +static void drbg_hmac_update(struct drbg_state *drbg, + const u8 *data1, size_t data1_len, + const u8 *data2, size_t data2_len) { - int ret = -EFAULT; - int i = 0; - struct drbg_string seed1, seed2, vdata; - LIST_HEAD(seedlist); - LIST_HEAD(vdatalist); - - if (!reseed) { - /* 10.1.2.3 step 2 -- memset(0) of C is implicit with kzalloc */ - memset(drbg->V, 1, drbg_statelen(drbg)); - drbg_kcapi_hmacsetkey(drbg, drbg->C); - } - - drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg)); - list_add_tail(&seed1.list, &seedlist); - /* buffer of seed2 will be filled in for loop below with one byte */ - drbg_string_fill(&seed2, NULL, 1); - list_add_tail(&seed2.list, &seedlist); - /* input data of seed is allowed to be NULL at this point */ - if (seed) - list_splice_tail(seed, &seedlist); + struct hmac_sha512_ctx hmac_ctx; + u8 new_key[DRBG_STATE_LEN]; - drbg_string_fill(&vdata, drbg->V, drbg_statelen(drbg)); - list_add_tail(&vdata.list, &vdatalist); - for (i = 2; 0 < i; i--) { - /* first round uses 0x0, second 0x1 */ - unsigned char prefix = DRBG_PREFIX0; - if (1 == i) - prefix = DRBG_PREFIX1; + for (u8 i = 0; i < 2; i++) { /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ - seed2.buf = &prefix; - ret = drbg_kcapi_hash(drbg, drbg->C, &seedlist); - if (ret) - return ret; - drbg_kcapi_hmacsetkey(drbg, drbg->C); + hmac_sha512_init(&hmac_ctx, &drbg->key); + hmac_sha512_update(&hmac_ctx, drbg->V, DRBG_STATE_LEN); + hmac_sha512_update(&hmac_ctx, &i, 1); + hmac_sha512_update(&hmac_ctx, data1, data1_len); + hmac_sha512_update(&hmac_ctx, data2, data2_len); + hmac_sha512_final(&hmac_ctx, new_key); + hmac_sha512_preparekey(&drbg->key, new_key, DRBG_STATE_LEN); /* 10.1.2.2 step 2 and 5 -- HMAC for V */ - ret = drbg_kcapi_hash(drbg, drbg->V, &vdatalist); - if (ret) - return ret; + hmac_sha512(&drbg->key, drbg->V, DRBG_STATE_LEN, drbg->V); /* 10.1.2.2 step 3 */ - if (!seed) - return ret; + if (data1_len == 0 && data2_len == 0) + break; } - - return 0; + memzero_explicit(new_key, sizeof(new_key)); } /* generate function of HMAC DRBG as defined in 10.1.2.5 */ -static int drbg_hmac_generate(struct drbg_state *drbg, - unsigned char *buf, - unsigned int buflen, - struct list_head *addtl) +static void drbg_hmac_generate(struct drbg_state *drbg, u8 *out, size_t outlen, + const u8 *addtl1, size_t addtl1_len) { - int len = 0; - int ret = 0; - struct drbg_string data; - LIST_HEAD(datalist); + u8 addtl2[32]; + size_t addtl2_len = 0; - /* 10.1.2.5 step 2 */ - if (addtl && !list_empty(addtl)) { - ret = drbg_hmac_update(drbg, addtl, 1); - if (ret) - return ret; + /* + * Append some bytes from get_random_bytes() to the additional input + * string, except when in test mode (as it would break the tests). + * Using a nonempty additional input string works around the forward + * secrecy bug in HMAC_DRBG described by Woodage & Shumow (2018) + * (https://eprint.iacr.org/2018/349.pdf). Filling the string with + * get_random_bytes() rather than a fixed value is safer still, and in + * particular makes random.c reseeds be immediately reflected. + * + * Note that there's no need to pull bytes from jitterentropy here too, + * since FIPS doesn't require any entropy in the additional input. + */ + if (drbg->test_entropylen == 0) { + get_random_bytes(addtl2, sizeof(addtl2)); + addtl2_len = sizeof(addtl2); } - drbg_string_fill(&data, drbg->V, drbg_statelen(drbg)); - list_add_tail(&data.list, &datalist); - while (len < buflen) { - unsigned int outlen = 0; + /* 10.1.2.5 step 2 */ + if (addtl1_len || addtl2_len) + drbg_hmac_update(drbg, addtl1, addtl1_len, addtl2, addtl2_len); + + while (outlen) { + size_t n = min(DRBG_STATE_LEN, outlen); + /* 10.1.2.5 step 4.1 */ - ret = drbg_kcapi_hash(drbg, drbg->V, &datalist); - if (ret) - return ret; - outlen = (drbg_blocklen(drbg) < (buflen - len)) ? - drbg_blocklen(drbg) : (buflen - len); + hmac_sha512(&drbg->key, drbg->V, DRBG_STATE_LEN, drbg->V); /* 10.1.2.5 step 4.2 */ - memcpy(buf + len, drbg->V, outlen); - len += outlen; + memcpy(out, drbg->V, n); + out += n; + outlen -= n; } /* 10.1.2.5 step 6 */ - if (addtl && !list_empty(addtl)) - ret = drbg_hmac_update(drbg, addtl, 1); - else - ret = drbg_hmac_update(drbg, NULL, 1); - if (ret) - return ret; + drbg_hmac_update(drbg, addtl1, addtl1_len, addtl2, addtl2_len); - return len; -} - -static const struct drbg_state_ops drbg_hmac_ops = { - .update = drbg_hmac_update, - .generate = drbg_hmac_generate, - .crypto_init = drbg_init_hash_kernel, - .crypto_fini = drbg_fini_hash_kernel, -}; -#endif /* CONFIG_CRYPTO_DRBG_HMAC */ - -/****************************************************************** - * Hash DRBG callback functions - ******************************************************************/ - -#ifdef CONFIG_CRYPTO_DRBG_HASH -#define CRYPTO_DRBG_HASH_STRING "HASH " -MODULE_ALIAS_CRYPTO("drbg_pr_sha512"); -MODULE_ALIAS_CRYPTO("drbg_nopr_sha512"); -MODULE_ALIAS_CRYPTO("drbg_pr_sha384"); -MODULE_ALIAS_CRYPTO("drbg_nopr_sha384"); -MODULE_ALIAS_CRYPTO("drbg_pr_sha256"); -MODULE_ALIAS_CRYPTO("drbg_nopr_sha256"); - -/* - * Increment buffer - * - * @dst buffer to increment - * @add value to add - */ -static inline void drbg_add_buf(unsigned char *dst, size_t dstlen, - const unsigned char *add, size_t addlen) -{ - /* implied: dstlen > addlen */ - unsigned char *dstptr; - const unsigned char *addptr; - unsigned int remainder = 0; - size_t len = addlen; - - dstptr = dst + (dstlen-1); - addptr = add + (addlen-1); - while (len) { - remainder += *dstptr + *addptr; - *dstptr = remainder & 0xff; - remainder >>= 8; - len--; dstptr--; addptr--; - } - len = dstlen - addlen; - while (len && remainder > 0) { - remainder = *dstptr + 1; - *dstptr = remainder & 0xff; - remainder >>= 8; - len--; dstptr--; - } -} - -/* - * scratchpad usage: as drbg_hash_update and drbg_hash_df are used - * interlinked, the scratchpad is used as follows: - * drbg_hash_update - * start: drbg->scratchpad - * length: drbg_statelen(drbg) - * drbg_hash_df: - * start: drbg->scratchpad + drbg_statelen(drbg) - * length: drbg_blocklen(drbg) - * - * drbg_hash_process_addtl uses the scratchpad, but fully completes - * before either of the functions mentioned before are invoked. Therefore, - * drbg_hash_process_addtl does not need to be specifically considered. - */ - -/* Derivation Function for Hash DRBG as defined in 10.4.1 */ -static int drbg_hash_df(struct drbg_state *drbg, - unsigned char *outval, size_t outlen, - struct list_head *entropylist) -{ - int ret = 0; - size_t len = 0; - unsigned char input[5]; - unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg); - struct drbg_string data; - - /* 10.4.1 step 3 */ - input[0] = 1; - drbg_cpu_to_be32((outlen * 8), &input[1]); - - /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ - drbg_string_fill(&data, input, 5); - list_add(&data.list, entropylist); - - /* 10.4.1 step 4 */ - while (len < outlen) { - short blocklen = 0; - /* 10.4.1 step 4.1 */ - ret = drbg_kcapi_hash(drbg, tmp, entropylist); - if (ret) - goto out; - /* 10.4.1 step 4.2 */ - input[0]++; - blocklen = (drbg_blocklen(drbg) < (outlen - len)) ? - drbg_blocklen(drbg) : (outlen - len); - memcpy(outval + len, tmp, blocklen); - len += blocklen; - } - -out: - memset(tmp, 0, drbg_blocklen(drbg)); - return ret; -} - -/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ -static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed, - int reseed) -{ - int ret = 0; - struct drbg_string data1, data2; - LIST_HEAD(datalist); - LIST_HEAD(datalist2); - unsigned char *V = drbg->scratchpad; - unsigned char prefix = DRBG_PREFIX1; - - if (!seed) - return -EINVAL; - - if (reseed) { - /* 10.1.1.3 step 1 */ - memcpy(V, drbg->V, drbg_statelen(drbg)); - drbg_string_fill(&data1, &prefix, 1); - list_add_tail(&data1.list, &datalist); - drbg_string_fill(&data2, V, drbg_statelen(drbg)); - list_add_tail(&data2.list, &datalist); - } - list_splice_tail(seed, &datalist); - - /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ - ret = drbg_hash_df(drbg, drbg->V, drbg_statelen(drbg), &datalist); - if (ret) - goto out; - - /* 10.1.1.2 / 10.1.1.3 step 4 */ - prefix = DRBG_PREFIX0; - drbg_string_fill(&data1, &prefix, 1); - list_add_tail(&data1.list, &datalist2); - drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); - list_add_tail(&data2.list, &datalist2); - /* 10.1.1.2 / 10.1.1.3 step 4 */ - ret = drbg_hash_df(drbg, drbg->C, drbg_statelen(drbg), &datalist2); - -out: - memset(drbg->scratchpad, 0, drbg_statelen(drbg)); - return ret; -} - -/* processing of additional information string for Hash DRBG */ -static int drbg_hash_process_addtl(struct drbg_state *drbg, - struct list_head *addtl) -{ - int ret = 0; - struct drbg_string data1, data2; - LIST_HEAD(datalist); - unsigned char prefix = DRBG_PREFIX2; - - /* 10.1.1.4 step 2 */ - if (!addtl || list_empty(addtl)) - return 0; - - /* 10.1.1.4 step 2a */ - drbg_string_fill(&data1, &prefix, 1); - drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); - list_add_tail(&data1.list, &datalist); - list_add_tail(&data2.list, &datalist); - list_splice_tail(addtl, &datalist); - ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist); - if (ret) - goto out; - - /* 10.1.1.4 step 2b */ - drbg_add_buf(drbg->V, drbg_statelen(drbg), - drbg->scratchpad, drbg_blocklen(drbg)); - -out: - memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); - return ret; -} - -/* Hashgen defined in 10.1.1.4 */ -static int drbg_hash_hashgen(struct drbg_state *drbg, - unsigned char *buf, - unsigned int buflen) -{ - int len = 0; - int ret = 0; - unsigned char *src = drbg->scratchpad; - unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg); - struct drbg_string data; - LIST_HEAD(datalist); - - /* 10.1.1.4 step hashgen 2 */ - memcpy(src, drbg->V, drbg_statelen(drbg)); - - drbg_string_fill(&data, src, drbg_statelen(drbg)); - list_add_tail(&data.list, &datalist); - while (len < buflen) { - unsigned int outlen = 0; - /* 10.1.1.4 step hashgen 4.1 */ - ret = drbg_kcapi_hash(drbg, dst, &datalist); - if (ret) { - len = ret; - goto out; - } - outlen = (drbg_blocklen(drbg) < (buflen - len)) ? - drbg_blocklen(drbg) : (buflen - len); - /* 10.1.1.4 step hashgen 4.2 */ - memcpy(buf + len, dst, outlen); - len += outlen; - /* 10.1.1.4 hashgen step 4.3 */ - if (len < buflen) - crypto_inc(src, drbg_statelen(drbg)); - } - -out: - memset(drbg->scratchpad, 0, - (drbg_statelen(drbg) + drbg_blocklen(drbg))); - return len; -} - -/* generate function for Hash DRBG as defined in 10.1.1.4 */ -static int drbg_hash_generate(struct drbg_state *drbg, - unsigned char *buf, unsigned int buflen, - struct list_head *addtl) -{ - int len = 0; - int ret = 0; - union { - unsigned char req[8]; - __be64 req_int; - } u; - unsigned char prefix = DRBG_PREFIX3; - struct drbg_string data1, data2; - LIST_HEAD(datalist); - - /* 10.1.1.4 step 2 */ - ret = drbg_hash_process_addtl(drbg, addtl); - if (ret) - return ret; - /* 10.1.1.4 step 3 */ - len = drbg_hash_hashgen(drbg, buf, buflen); - - /* this is the value H as documented in 10.1.1.4 */ - /* 10.1.1.4 step 4 */ - drbg_string_fill(&data1, &prefix, 1); - list_add_tail(&data1.list, &datalist); - drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); - list_add_tail(&data2.list, &datalist); - ret = drbg_kcapi_hash(drbg, drbg->scratchpad, &datalist); - if (ret) { - len = ret; - goto out; - } - - /* 10.1.1.4 step 5 */ - drbg_add_buf(drbg->V, drbg_statelen(drbg), - drbg->scratchpad, drbg_blocklen(drbg)); - drbg_add_buf(drbg->V, drbg_statelen(drbg), - drbg->C, drbg_statelen(drbg)); - u.req_int = cpu_to_be64(drbg->reseed_ctr); - drbg_add_buf(drbg->V, drbg_statelen(drbg), u.req, 8); - -out: - memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); - return len; -} - -/* - * scratchpad usage: as update and generate are used isolated, both - * can use the scratchpad - */ -static const struct drbg_state_ops drbg_hash_ops = { - .update = drbg_hash_update, - .generate = drbg_hash_generate, - .crypto_init = drbg_init_hash_kernel, - .crypto_fini = drbg_fini_hash_kernel, -}; -#endif /* CONFIG_CRYPTO_DRBG_HASH */ - -/****************************************************************** - * Functions common for DRBG implementations - ******************************************************************/ - -static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed, - int reseed, enum drbg_seed_state new_seed_state) -{ - int ret = drbg->d_ops->update(drbg, seed, reseed); - - if (ret) - return ret; - - drbg->seeded = new_seed_state; - drbg->last_seed_time = jiffies; - /* 10.1.1.2 / 10.1.1.3 step 5 */ - drbg->reseed_ctr = 1; - - switch (drbg->seeded) { - case DRBG_SEED_STATE_UNSEEDED: - /* Impossible, but handle it to silence compiler warnings. */ - fallthrough; - case DRBG_SEED_STATE_PARTIAL: - /* - * Require frequent reseeds until the seed source is - * fully initialized. - */ - drbg->reseed_threshold = 50; - break; - - case DRBG_SEED_STATE_FULL: - /* - * Seed source has become fully initialized, frequent - * reseeds no longer required. - */ - drbg->reseed_threshold = drbg_max_requests(drbg); - break; - } - - return ret; -} - -static inline void drbg_get_random_bytes(struct drbg_state *drbg, - unsigned char *entropy, - unsigned int entropylen) - __must_hold(&drbg->drbg_mutex) -{ - do - get_random_bytes(entropy, entropylen); - while (!drbg_fips_continuous_test(drbg, entropy)); -} - -static int drbg_seed_from_random(struct drbg_state *drbg) - __must_hold(&drbg->drbg_mutex) -{ - struct drbg_string data; - LIST_HEAD(seedlist); - unsigned int entropylen = drbg_sec_strength(drbg->core->flags); - unsigned char entropy[32]; - int ret; - - BUG_ON(!entropylen); - BUG_ON(entropylen > sizeof(entropy)); - - drbg_string_fill(&data, entropy, entropylen); - list_add_tail(&data.list, &seedlist); - - drbg_get_random_bytes(drbg, entropy, entropylen); - - ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL); - - memzero_explicit(entropy, entropylen); - return ret; -} - -static bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg) -{ - unsigned long next_reseed; - - /* Don't ever reseed from get_random_bytes() in test mode. */ - if (list_empty(&drbg->test_data.list)) - return false; - - /* - * Obtain fresh entropy for the nopr DRBGs after 300s have - * elapsed in order to still achieve sort of partial - * prediction resistance over the time domain at least. Note - * that the period of 300s has been chosen to match the - * CRNG_RESEED_INTERVAL of the get_random_bytes()' chacha - * rngs. - */ - next_reseed = drbg->last_seed_time + 300 * HZ; - return time_after(jiffies, next_reseed); + memzero_explicit(addtl2, sizeof(addtl2)); } /* @@ -901,33 +218,32 @@ static bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg) * * @drbg: DRBG state struct * @pers: personalization / additional information buffer - * @reseed: 0 for initial seed process, 1 for reseeding + * @pers_len: length of @pers in bytes + * @reseed: false for initial seeding (instantiation), true for reseeding * * return: * 0 on success * error value otherwise */ -static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, +static int drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len, bool reseed) __must_hold(&drbg->drbg_mutex) { int ret; - unsigned char entropy[((32 + 16) * 2)]; - unsigned int entropylen = drbg_sec_strength(drbg->core->flags); - struct drbg_string data1; - LIST_HEAD(seedlist); - enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL; + u8 entropy_buf[(32 + 16) * 2]; + size_t entropylen; + const u8 *entropy; /* 9.1 / 9.2 / 9.3.1 step 3 */ - if (pers && pers->len > (drbg_max_addtl(drbg))) { + if (pers_len > DRBG_MAX_ADDTL_BYTES) { pr_devel("DRBG: personalization string too long %zu\n", - pers->len); + pers_len); return -EINVAL; } - if (list_empty(&drbg->test_data.list)) { - drbg_string_fill(&data1, drbg->test_data.buf, - drbg->test_data.len); + if (drbg->test_entropylen) { + entropy = drbg->test_entropy; + entropylen = drbg->test_entropylen; pr_devel("DRBG: using test entropy\n"); } else { /* @@ -938,20 +254,18 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, * of the strength. The consideration of a nonce is only * applicable during initial seeding. */ - BUG_ON(!entropylen); + entropy = entropy_buf; if (!reseed) - entropylen = ((entropylen + 1) / 2) * 3; - BUG_ON((entropylen * 2) > sizeof(entropy)); + entropylen = ((DRBG_SEC_STRENGTH + 1) / 2) * 3; + else + entropylen = DRBG_SEC_STRENGTH; + BUG_ON(entropylen * 2 > sizeof(entropy_buf)); /* Get seed from in-kernel /dev/urandom */ - if (!rng_is_initialized()) - new_seed_state = DRBG_SEED_STATE_PARTIAL; - - drbg_get_random_bytes(drbg, entropy, entropylen); + get_random_bytes(entropy_buf, entropylen); if (!drbg->jent) { - drbg_string_fill(&data1, entropy, entropylen); - pr_devel("DRBG: (re)seeding with %u bytes of entropy\n", + pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n", entropylen); } else { /* @@ -959,7 +273,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, * fatal only in FIPS mode. */ ret = crypto_rng_get_bytes(drbg->jent, - entropy + entropylen, + &entropy_buf[entropylen], entropylen); if (fips_enabled && ret) { pr_devel("DRBG: jent failed with %d\n", ret); @@ -982,238 +296,94 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, goto out; } - drbg_string_fill(&data1, entropy, entropylen * 2); - pr_devel("DRBG: (re)seeding with %u bytes of entropy\n", - entropylen * 2); + entropylen *= 2; + pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n", + entropylen); } } - list_add_tail(&data1.list, &seedlist); - /* - * concatenation of entropy with personalization str / addtl input) - * the variable pers is directly handed in by the caller, so check its - * contents whether it is appropriate - */ - if (pers && pers->buf && 0 < pers->len) { - list_add_tail(&pers->list, &seedlist); + if (pers_len) pr_devel("DRBG: using personalization string\n"); - } - - if (!reseed) { - memset(drbg->V, 0, drbg_statelen(drbg)); - memset(drbg->C, 0, drbg_statelen(drbg)); - } - - ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state); + drbg_hmac_update(drbg, entropy, entropylen, pers, pers_len); + drbg->reseed_ctr = 1; + ret = 0; out: - memzero_explicit(entropy, entropylen * 2); - - return ret; -} - -/* Free all substructures in a DRBG state without the DRBG state structure */ -static inline void drbg_dealloc_state(struct drbg_state *drbg) -{ - if (!drbg) - return; - kfree_sensitive(drbg->Vbuf); - drbg->Vbuf = NULL; - drbg->V = NULL; - kfree_sensitive(drbg->Cbuf); - drbg->Cbuf = NULL; - drbg->C = NULL; - kfree_sensitive(drbg->scratchpadbuf); - drbg->scratchpadbuf = NULL; - drbg->reseed_ctr = 0; - drbg->d_ops = NULL; - drbg->core = NULL; - if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) { - kfree_sensitive(drbg->prev); - drbg->prev = NULL; - drbg->fips_primed = false; - } -} - -/* - * Allocate all sub-structures for a DRBG state. - * The DRBG state structure must already be allocated. - */ -static inline int drbg_alloc_state(struct drbg_state *drbg) -{ - int ret = -ENOMEM; - unsigned int sb_size = 0; + memzero_explicit(entropy_buf, sizeof(entropy_buf)); - switch (drbg->core->flags & DRBG_TYPE_MASK) { -#ifdef CONFIG_CRYPTO_DRBG_HMAC - case DRBG_HMAC: - drbg->d_ops = &drbg_hmac_ops; - break; -#endif /* CONFIG_CRYPTO_DRBG_HMAC */ -#ifdef CONFIG_CRYPTO_DRBG_HASH - case DRBG_HASH: - drbg->d_ops = &drbg_hash_ops; - break; -#endif /* CONFIG_CRYPTO_DRBG_HASH */ -#ifdef CONFIG_CRYPTO_DRBG_CTR - case DRBG_CTR: - drbg->d_ops = &drbg_ctr_ops; - break; -#endif /* CONFIG_CRYPTO_DRBG_CTR */ - default: - ret = -EOPNOTSUPP; - goto err; - } - - ret = drbg->d_ops->crypto_init(drbg); - if (ret < 0) - goto err; - - drbg->Vbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL); - if (!drbg->Vbuf) { - ret = -ENOMEM; - goto fini; - } - drbg->V = PTR_ALIGN(drbg->Vbuf, ret + 1); - drbg->Cbuf = kmalloc(drbg_statelen(drbg) + ret, GFP_KERNEL); - if (!drbg->Cbuf) { - ret = -ENOMEM; - goto fini; - } - drbg->C = PTR_ALIGN(drbg->Cbuf, ret + 1); - /* scratchpad is only generated for CTR and Hash */ - if (drbg->core->flags & DRBG_HMAC) - sb_size = 0; - else if (drbg->core->flags & DRBG_CTR) - sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg) + /* temp */ - crypto_drbg_ctr_df_datalen(drbg_statelen(drbg), - drbg_blocklen(drbg)); - else - sb_size = drbg_statelen(drbg) + drbg_blocklen(drbg); - - if (0 < sb_size) { - drbg->scratchpadbuf = kzalloc(sb_size + ret, GFP_KERNEL); - if (!drbg->scratchpadbuf) { - ret = -ENOMEM; - goto fini; - } - drbg->scratchpad = PTR_ALIGN(drbg->scratchpadbuf, ret + 1); - } - - if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) { - drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags), - GFP_KERNEL); - if (!drbg->prev) { - ret = -ENOMEM; - goto fini; - } - drbg->fips_primed = false; - } - - return 0; - -fini: - drbg->d_ops->crypto_fini(drbg); -err: - drbg_dealloc_state(drbg); return ret; } -/************************************************************************* - * DRBG interface functions - *************************************************************************/ - /* - * DRBG generate function as required by SP800-90A - this function - * generates random numbers + * Generate random bytes from an SP800-90A DRBG. * * @drbg DRBG state handle - * @buf Buffer where to store the random numbers -- the buffer must already - * be pre-allocated by caller - * @buflen Length of output buffer - this value defines the number of random - * bytes pulled from DRBG - * @addtl Additional input that is mixed into state, may be NULL -- note - * the entropy is pulled by the DRBG internally unconditionally - * as defined in SP800-90A. The additional input is mixed into - * the state in addition to the pulled entropy. + * @out Buffer where to store the random bytes + * @outlen Number of random bytes to generate + * @addtl Optional additional input that is mixed into state + * @addtl_len Length of @addtl in bytes, may be 0 * * return: 0 when all bytes are generated; < 0 in case of an error */ -static int drbg_generate(struct drbg_state *drbg, - unsigned char *buf, unsigned int buflen, - struct drbg_string *addtl) +static int drbg_generate(struct drbg_state *drbg, u8 *out, size_t outlen, + const u8 *addtl, size_t addtl_len) __must_hold(&drbg->drbg_mutex) { - int len = 0; - LIST_HEAD(addtllist); + int err; - if (!drbg->core) { - pr_devel("DRBG: not yet seeded\n"); + if (!drbg->instantiated) { + pr_devel("DRBG: not yet instantiated\n"); return -EINVAL; } - if (0 == buflen || !buf) { + if (out == NULL || outlen == 0) { pr_devel("DRBG: no output buffer provided\n"); return -EINVAL; } - if (addtl && NULL == addtl->buf && 0 < addtl->len) { + if (addtl == NULL && addtl_len != 0) { pr_devel("DRBG: wrong format of additional information\n"); return -EINVAL; } /* 9.3.1 step 2 */ - len = -EINVAL; - if (buflen > (drbg_max_request_bytes(drbg))) { - pr_devel("DRBG: requested random numbers too large %u\n", - buflen); - goto err; + if (outlen > DRBG_MAX_REQUEST_BYTES) { + pr_devel("DRBG: request length is too long %zu\n", outlen); + return -EINVAL; } /* 9.3.1 step 3 is implicit with the chosen DRBG */ /* 9.3.1 step 4 */ - if (addtl && addtl->len > (drbg_max_addtl(drbg))) { + if (addtl_len > DRBG_MAX_ADDTL_BYTES) { pr_devel("DRBG: additional information string too long %zu\n", - addtl->len); - goto err; + addtl_len); + return -EINVAL; } /* 9.3.1 step 5 is implicit with the chosen DRBG */ /* * 9.3.1 step 6 and 9 supplemented by 9.3.2 step c is implemented * here. The spec is a bit convoluted here, we make it simpler. + * + * We no longer try to detect when random.c has reseeded itself and call + * drbg_seed() then too, since drbg_hmac_generate() adds bytes from + * random.c to the additional input, which is a de facto reseed anyway. */ - if (drbg->reseed_threshold < drbg->reseed_ctr) - drbg->seeded = DRBG_SEED_STATE_UNSEEDED; - - if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) { - pr_devel("DRBG: reseeding before generation (prediction " - "resistance: %s, state %s)\n", - str_true_false(drbg->pr), - (drbg->seeded == DRBG_SEED_STATE_FULL ? - "seeded" : "unseeded")); + if (drbg->reseed_ctr > DRBG_MAX_REQUESTS) { + pr_devel("DRBG: reseeding before generation\n"); /* 9.3.1 steps 7.1 through 7.3 */ - len = drbg_seed(drbg, addtl, true); - if (len) - goto err; + err = drbg_seed(drbg, addtl, addtl_len, true); + if (err) + return err; /* 9.3.1 step 7.4 */ addtl = NULL; - } else if (rng_is_initialized() && - (drbg->seeded == DRBG_SEED_STATE_PARTIAL || - drbg_nopr_reseed_interval_elapsed(drbg))) { - len = drbg_seed_from_random(drbg); - if (len) - goto err; + addtl_len = 0; } - if (addtl && 0 < addtl->len) - list_add_tail(&addtl->list, &addtllist); /* 9.3.1 step 8 and 10 */ - len = drbg->d_ops->generate(drbg, buf, buflen, &addtllist); + drbg_hmac_generate(drbg, out, outlen, addtl, addtl_len); - /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ + /* 10.1.2.5 step 7 */ drbg->reseed_ctr++; - if (0 >= len) - goto err; /* * Section 11.3.3 requires to re-perform self tests after some @@ -1226,504 +396,126 @@ static int drbg_generate(struct drbg_state *drbg, * In this case, the entire kernel operation is questionable and it * is unlikely that the integrity violation only affects the * correct operation of the DRBG. - * - * Albeit the following code is commented out, it is provided in - * case somebody has a need to implement the test of 11.3.3. */ -#if 0 - if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) { - int err = 0; - pr_devel("DRBG: start to perform self test\n"); - if (drbg->core->flags & DRBG_HMAC) - err = alg_test("drbg_pr_hmac_sha512", - "drbg_pr_hmac_sha512", 0, 0); - else if (drbg->core->flags & DRBG_CTR) - err = alg_test("drbg_pr_ctr_aes256", - "drbg_pr_ctr_aes256", 0, 0); - else - err = alg_test("drbg_pr_sha256", - "drbg_pr_sha256", 0, 0); - if (err) { - pr_err("DRBG: periodical self test failed\n"); - /* - * uninstantiate implies that from now on, only errors - * are returned when reusing this DRBG cipher handle - */ - drbg_uninstantiate(drbg); - return 0; - } else { - pr_devel("DRBG: self test successful\n"); - } - } -#endif - /* - * All operations were successful, return 0 as mandated by - * the kernel crypto API interface. - */ - len = 0; -err: - return len; -} - -/* - * Wrapper around drbg_generate which can pull arbitrary long strings - * from the DRBG without hitting the maximum request limitation. - * - * Parameters: see drbg_generate - * Return codes: see drbg_generate -- if one drbg_generate request fails, - * the entire drbg_generate_long request fails - */ -static int drbg_generate_long(struct drbg_state *drbg, - unsigned char *buf, unsigned int buflen, - struct drbg_string *addtl) -{ - unsigned int len = 0; - unsigned int slice = 0; - do { - int err = 0; - unsigned int chunk = 0; - slice = ((buflen - len) / drbg_max_request_bytes(drbg)); - chunk = slice ? drbg_max_request_bytes(drbg) : (buflen - len); - mutex_lock(&drbg->drbg_mutex); - err = drbg_generate(drbg, buf + len, chunk, addtl); - mutex_unlock(&drbg->drbg_mutex); - if (0 > err) - return err; - len += chunk; - } while (slice > 0 && (len < buflen)); return 0; } -static int drbg_prepare_hrng(struct drbg_state *drbg) -{ - /* We do not need an HRNG in test mode. */ - if (list_empty(&drbg->test_data.list)) - return 0; - - drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); - if (IS_ERR(drbg->jent)) { - const int err = PTR_ERR(drbg->jent); - - drbg->jent = NULL; - if (fips_enabled) - return err; - pr_info("DRBG: Continuing without Jitter RNG\n"); - } - - return 0; -} +/*************************************************************** + * Kernel crypto API interface to DRBG + ***************************************************************/ -/* - * DRBG instantiation function as required by SP800-90A - this function - * sets up the DRBG handle, performs the initial seeding and all sanity - * checks required by SP800-90A - * - * @drbg memory of state -- if NULL, new memory is allocated - * @pers Personalization string that is mixed into state, may be NULL -- note - * the entropy is pulled by the DRBG internally unconditionally - * as defined in SP800-90A. The additional input is mixed into - * the state in addition to the pulled entropy. - * @coreref reference to core - * @pr prediction resistance enabled - * - * return - * 0 on success - * error value otherwise - */ -static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, - int coreref, bool pr) +static int drbg_kcapi_init(struct crypto_tfm *tfm) { - int ret; - bool reseed = true; - - pr_devel("DRBG: Initializing DRBG core %d with prediction resistance " - "%s\n", coreref, str_enabled_disabled(pr)); - mutex_lock(&drbg->drbg_mutex); - - /* 9.1 step 1 is implicit with the selected DRBG type */ - - /* - * 9.1 step 2 is implicit as caller can select prediction resistance - * and the flag is copied into drbg->flags -- - * all DRBG types support prediction resistance - */ - - /* 9.1 step 4 is implicit in drbg_sec_strength */ - - if (!drbg->core) { - drbg->core = &drbg_cores[coreref]; - drbg->pr = pr; - drbg->seeded = DRBG_SEED_STATE_UNSEEDED; - drbg->last_seed_time = 0; - drbg->reseed_threshold = drbg_max_requests(drbg); - - ret = drbg_alloc_state(drbg); - if (ret) - goto unlock; - - ret = drbg_prepare_hrng(drbg); - if (ret) - goto free_everything; - - reseed = false; - } - - ret = drbg_seed(drbg, pers, reseed); - - if (ret && !reseed) - goto free_everything; - - mutex_unlock(&drbg->drbg_mutex); - return ret; - -unlock: - mutex_unlock(&drbg->drbg_mutex); - return ret; - -free_everything: - mutex_unlock(&drbg->drbg_mutex); - drbg_uninstantiate(drbg); - return ret; -} + struct drbg_state *drbg = crypto_tfm_ctx(tfm); -/* - * DRBG uninstantiate function as required by SP800-90A - this function - * frees all buffers and the DRBG handle - * - * @drbg DRBG state handle - * - * return - * 0 on success - */ -static int drbg_uninstantiate(struct drbg_state *drbg) -{ - if (!IS_ERR_OR_NULL(drbg->jent)) - crypto_free_rng(drbg->jent); - drbg->jent = NULL; + mutex_init(&drbg->drbg_mutex); - if (drbg->d_ops) - drbg->d_ops->crypto_fini(drbg); - drbg_dealloc_state(drbg); - /* no scrubbing of test_data -- this shall survive an uninstantiate */ return 0; } -/* - * Helper function for setting the test data in the DRBG - * - * @drbg DRBG state handle - * @data test data - * @len test data length - */ +/* Set test entropy in the DRBG. */ static void drbg_kcapi_set_entropy(struct crypto_rng *tfm, const u8 *data, unsigned int len) { struct drbg_state *drbg = crypto_rng_ctx(tfm); mutex_lock(&drbg->drbg_mutex); - drbg_string_fill(&drbg->test_data, data, len); + drbg->test_entropy = data; + drbg->test_entropylen = len; mutex_unlock(&drbg->drbg_mutex); } -/*************************************************************** - * Kernel crypto API cipher invocations requested by DRBG - ***************************************************************/ - -#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC) -struct sdesc { - struct shash_desc shash; -}; - -static int drbg_init_hash_kernel(struct drbg_state *drbg) -{ - struct sdesc *sdesc; - struct crypto_shash *tfm; - - tfm = crypto_alloc_shash(drbg->core->backend_cra_name, 0, 0); - if (IS_ERR(tfm)) { - pr_info("DRBG: could not allocate digest TFM handle: %s\n", - drbg->core->backend_cra_name); - return PTR_ERR(tfm); - } - BUG_ON(drbg_blocklen(drbg) != crypto_shash_digestsize(tfm)); - sdesc = kzalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm), - GFP_KERNEL); - if (!sdesc) { - crypto_free_shash(tfm); - return -ENOMEM; - } - - sdesc->shash.tfm = tfm; - drbg->priv_data = sdesc; - - return 0; -} - -static int drbg_fini_hash_kernel(struct drbg_state *drbg) -{ - struct sdesc *sdesc = drbg->priv_data; - if (sdesc) { - crypto_free_shash(sdesc->shash.tfm); - kfree_sensitive(sdesc); - } - drbg->priv_data = NULL; - return 0; -} - -static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg, - const unsigned char *key) -{ - struct sdesc *sdesc = drbg->priv_data; - - crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg)); -} - -static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval, - const struct list_head *in) -{ - struct sdesc *sdesc = drbg->priv_data; - struct drbg_string *input = NULL; - - crypto_shash_init(&sdesc->shash); - list_for_each_entry(input, in, list) - crypto_shash_update(&sdesc->shash, input->buf, input->len); - return crypto_shash_final(&sdesc->shash, outval); -} -#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ - -#ifdef CONFIG_CRYPTO_DRBG_CTR -static int drbg_fini_sym_kernel(struct drbg_state *drbg) -{ - struct aes_enckey *aeskey = drbg->priv_data; - - kfree(aeskey); - drbg->priv_data = NULL; - - if (drbg->ctr_handle) - crypto_free_skcipher(drbg->ctr_handle); - drbg->ctr_handle = NULL; - - if (drbg->ctr_req) - skcipher_request_free(drbg->ctr_req); - drbg->ctr_req = NULL; - - kfree(drbg->outscratchpadbuf); - drbg->outscratchpadbuf = NULL; - - return 0; -} - -static int drbg_init_sym_kernel(struct drbg_state *drbg) -{ - struct aes_enckey *aeskey; - struct crypto_skcipher *sk_tfm; - struct skcipher_request *req; - unsigned int alignmask; - char ctr_name[CRYPTO_MAX_ALG_NAME]; - - aeskey = kzalloc_obj(*aeskey); - if (!aeskey) - return -ENOMEM; - drbg->priv_data = aeskey; - - if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)", - drbg->core->backend_cra_name) >= CRYPTO_MAX_ALG_NAME) { - drbg_fini_sym_kernel(drbg); - return -EINVAL; - } - sk_tfm = crypto_alloc_skcipher(ctr_name, 0, 0); - if (IS_ERR(sk_tfm)) { - pr_info("DRBG: could not allocate CTR cipher TFM handle: %s\n", - ctr_name); - drbg_fini_sym_kernel(drbg); - return PTR_ERR(sk_tfm); - } - drbg->ctr_handle = sk_tfm; - crypto_init_wait(&drbg->ctr_wait); - - req = skcipher_request_alloc(sk_tfm, GFP_KERNEL); - if (!req) { - pr_info("DRBG: could not allocate request queue\n"); - drbg_fini_sym_kernel(drbg); - return -ENOMEM; - } - drbg->ctr_req = req; - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP, - crypto_req_done, &drbg->ctr_wait); - - alignmask = crypto_skcipher_alignmask(sk_tfm); - drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask, - GFP_KERNEL); - if (!drbg->outscratchpadbuf) { - drbg_fini_sym_kernel(drbg); - return -ENOMEM; - } - drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf, - alignmask + 1); - - sg_init_table(&drbg->sg_in, 1); - sg_init_one(&drbg->sg_out, drbg->outscratchpad, DRBG_OUTSCRATCHLEN); - - return alignmask; -} - -static int drbg_kcapi_sym_ctr(struct drbg_state *drbg, - u8 *inbuf, u32 inlen, - u8 *outbuf, u32 outlen) +/* Seed (i.e. instantiate) or re-seed the DRBG. */ +static int drbg_kcapi_seed(struct crypto_rng *tfm, + const u8 *pers, unsigned int pers_len) { - struct scatterlist *sg_in = &drbg->sg_in, *sg_out = &drbg->sg_out; - u32 scratchpad_use = min_t(u32, outlen, DRBG_OUTSCRATCHLEN); + static const u8 initial_key[DRBG_STATE_LEN]; /* all zeroes */ + struct drbg_state *drbg = crypto_rng_ctx(tfm); int ret; - if (inbuf) { - /* Use caller-provided input buffer */ - sg_set_buf(sg_in, inbuf, inlen); - } else { - /* Use scratchpad for in-place operation */ - inlen = scratchpad_use; - memset(drbg->outscratchpad, 0, scratchpad_use); - sg_set_buf(sg_in, drbg->outscratchpad, scratchpad_use); - } - - while (outlen) { - u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN); + pr_devel("DRBG: Initializing DRBG\n"); + guard(mutex)(&drbg->drbg_mutex); - /* Output buffer may not be valid for SGL, use scratchpad */ - skcipher_request_set_crypt(drbg->ctr_req, sg_in, sg_out, - cryptlen, drbg->V); - ret = crypto_wait_req(crypto_skcipher_encrypt(drbg->ctr_req), - &drbg->ctr_wait); - if (ret) - goto out; + if (drbg->instantiated) + return drbg_seed(drbg, pers, pers_len, /* reseed= */ true); - crypto_init_wait(&drbg->ctr_wait); - - memcpy(outbuf, drbg->outscratchpad, cryptlen); - memzero_explicit(drbg->outscratchpad, cryptlen); - - outlen -= cryptlen; - outbuf += cryptlen; - } - ret = 0; - -out: - return ret; -} -#endif /* CONFIG_CRYPTO_DRBG_CTR */ + /* 9.1 step 1 is implicit with the selected DRBG type */ -/*************************************************************** - * Kernel crypto API interface to register DRBG - ***************************************************************/ + /* + * 9.1 step 2 is implicit, as this implementation doesn't support + * prediction resistance + */ -/* - * Look up the DRBG flags by given kernel crypto API cra_name - * The code uses the drbg_cores definition to do this - * - * @cra_name kernel crypto API cra_name - * @coreref reference to integer which is filled with the pointer to - * the applicable core - * @pr reference for setting prediction resistance - * - * return: flags - */ -static inline void drbg_convert_tfm_core(const char *cra_driver_name, - int *coreref, bool *pr) -{ - int i = 0; - size_t start = 0; - int len = 0; + /* 9.1 step 4 is implicit in DRBG_SEC_STRENGTH */ - *pr = true; - /* disassemble the names */ - if (!memcmp(cra_driver_name, "drbg_nopr_", 10)) { - start = 10; - *pr = false; - } else if (!memcmp(cra_driver_name, "drbg_pr_", 8)) { - start = 8; - } else { - return; - } + memset(drbg->V, 1, DRBG_STATE_LEN); + hmac_sha512_preparekey(&drbg->key, initial_key, DRBG_STATE_LEN); - /* remove the first part */ - len = strlen(cra_driver_name) - start; - for (i = 0; ARRAY_SIZE(drbg_cores) > i; i++) { - if (!memcmp(cra_driver_name + start, drbg_cores[i].cra_name, - len)) { - *coreref = i; - return; + /* Allocate jitterentropy_rng if not in test mode. */ + if (drbg->test_entropylen == 0) { + drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); + if (IS_ERR(drbg->jent)) { + ret = PTR_ERR(drbg->jent); + drbg->jent = NULL; + if (fips_enabled) + return ret; + pr_info("DRBG: Continuing without Jitter RNG\n"); } } -} - -static int drbg_kcapi_init(struct crypto_tfm *tfm) -{ - struct drbg_state *drbg = crypto_tfm_ctx(tfm); - - mutex_init(&drbg->drbg_mutex); + ret = drbg_seed(drbg, pers, pers_len, /* reseed= */ false); + if (ret) { + crypto_free_rng(drbg->jent); + drbg->jent = NULL; + return ret; + } + drbg->instantiated = true; return 0; } -static void drbg_kcapi_cleanup(struct crypto_tfm *tfm) -{ - drbg_uninstantiate(crypto_tfm_ctx(tfm)); -} - /* * Generate random numbers invoked by the kernel crypto API: - * The API of the kernel crypto API is extended as follows: * * src is additional input supplied to the RNG. * slen is the length of src. * dst is the output buffer where random data is to be stored. * dlen is the length of dst. */ -static int drbg_kcapi_random(struct crypto_rng *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int dlen) +static int drbg_kcapi_generate(struct crypto_rng *tfm, + const u8 *src, unsigned int slen, + u8 *dst, unsigned int dlen) { struct drbg_state *drbg = crypto_rng_ctx(tfm); - struct drbg_string *addtl = NULL; - struct drbg_string string; - if (slen) { - /* linked list variable is now local to allow modification */ - drbg_string_fill(&string, src, slen); - addtl = &string; - } + /* + * Break the request into multiple requests if needed, to avoid + * exceeding the maximum request length of the core algorithm. + */ + do { + unsigned int n = min(dlen, DRBG_MAX_REQUEST_BYTES); + int err; - return drbg_generate_long(drbg, dst, dlen, addtl); + mutex_lock(&drbg->drbg_mutex); + err = drbg_generate(drbg, dst, n, src, slen); + mutex_unlock(&drbg->drbg_mutex); + if (err < 0) + return err; + dst += n; + dlen -= n; + } while (dlen); + return 0; } -/* - * Seed the DRBG invoked by the kernel crypto API - */ -static int drbg_kcapi_seed(struct crypto_rng *tfm, - const u8 *seed, unsigned int slen) +/* Uninstantiate the DRBG. */ +static void drbg_kcapi_exit(struct crypto_tfm *tfm) { - struct drbg_state *drbg = crypto_rng_ctx(tfm); - struct crypto_tfm *tfm_base = crypto_rng_tfm(tfm); - bool pr = false; - struct drbg_string string; - struct drbg_string *seed_string = NULL; - int coreref = 0; - - drbg_convert_tfm_core(crypto_tfm_alg_driver_name(tfm_base), &coreref, - &pr); - if (0 < slen) { - drbg_string_fill(&string, seed, slen); - seed_string = &string; - } + struct drbg_state *drbg = crypto_tfm_ctx(tfm); - return drbg_instantiate(drbg, seed_string, coreref, pr); + crypto_free_rng(drbg->jent); + memzero_explicit(drbg, sizeof(*drbg)); } -/*************************************************************** - * Kernel module: code to load the module - ***************************************************************/ - /* * Tests as defined in 11.3.2 in addition to the cipher tests: testing * of the error handling. @@ -1736,38 +528,21 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm, */ static inline int __init drbg_healthcheck_sanity(void) { - int len = 0; #define OUTBUFLEN 16 - unsigned char buf[OUTBUFLEN]; + u8 buf[OUTBUFLEN]; struct drbg_state *drbg = NULL; int ret; - int rc = -EFAULT; - bool pr = false; - int coreref = 0; - struct drbg_string addtl; - size_t max_addtllen, max_request_bytes; /* only perform test in FIPS mode */ if (!fips_enabled) return 0; -#ifdef CONFIG_CRYPTO_DRBG_CTR - drbg_convert_tfm_core("drbg_nopr_ctr_aes256", &coreref, &pr); -#endif -#ifdef CONFIG_CRYPTO_DRBG_HASH - drbg_convert_tfm_core("drbg_nopr_sha256", &coreref, &pr); -#endif -#ifdef CONFIG_CRYPTO_DRBG_HMAC - drbg_convert_tfm_core("drbg_nopr_hmac_sha512", &coreref, &pr); -#endif - drbg = kzalloc_obj(struct drbg_state); if (!drbg) return -ENOMEM; guard(mutex_init)(&drbg->drbg_mutex); - drbg->core = &drbg_cores[coreref]; - drbg->reseed_threshold = drbg_max_requests(drbg); + drbg->instantiated = true; /* * if the following tests fail, it is likely that there is a buffer @@ -1777,128 +552,66 @@ static inline int __init drbg_healthcheck_sanity(void) * grave bug. */ - max_addtllen = drbg_max_addtl(drbg); - max_request_bytes = drbg_max_request_bytes(drbg); - drbg_string_fill(&addtl, buf, max_addtllen + 1); /* overflow addtllen with additional info string */ - len = drbg_generate(drbg, buf, OUTBUFLEN, &addtl); - BUG_ON(0 < len); + ret = drbg_generate(drbg, buf, OUTBUFLEN, buf, + DRBG_MAX_ADDTL_BYTES + 1); + BUG_ON(ret == 0); /* overflow max_bits */ - len = drbg_generate(drbg, buf, (max_request_bytes + 1), NULL); - BUG_ON(0 < len); + ret = drbg_generate(drbg, buf, DRBG_MAX_REQUEST_BYTES + 1, NULL, 0); + BUG_ON(ret == 0); /* overflow max addtllen with personalization string */ - ret = drbg_seed(drbg, &addtl, false); - BUG_ON(0 == ret); + ret = drbg_seed(drbg, buf, DRBG_MAX_ADDTL_BYTES + 1, false); + BUG_ON(ret == 0); /* all tests passed */ - rc = 0; pr_devel("DRBG: Sanity tests for failure code paths successfully " "completed\n"); kfree(drbg); - return rc; + return 0; } -static struct rng_alg drbg_algs[22]; - -/* - * Fill the array drbg_algs used to register the different DRBGs - * with the kernel crypto API. To fill the array, the information - * from drbg_cores[] is used. - */ -static inline void __init drbg_fill_array(struct rng_alg *alg, - const struct drbg_core *core, int pr) -{ - int pos = 0; - static int priority = 200; - - memcpy(alg->base.cra_name, "stdrng", 6); - if (pr) { - memcpy(alg->base.cra_driver_name, "drbg_pr_", 8); - pos = 8; - } else { - memcpy(alg->base.cra_driver_name, "drbg_nopr_", 10); - pos = 10; - } - memcpy(alg->base.cra_driver_name + pos, core->cra_name, - strlen(core->cra_name)); - - alg->base.cra_priority = priority; - priority++; - /* - * If FIPS mode enabled, the selected DRBG shall have the - * highest cra_priority over other stdrng instances to ensure - * it is selected. - */ - if (fips_enabled) - alg->base.cra_priority += 200; - - alg->base.cra_ctxsize = sizeof(struct drbg_state); - alg->base.cra_module = THIS_MODULE; - alg->base.cra_init = drbg_kcapi_init; - alg->base.cra_exit = drbg_kcapi_cleanup; - alg->generate = drbg_kcapi_random; - alg->seed = drbg_kcapi_seed; - alg->set_ent = drbg_kcapi_set_entropy; - alg->seedsize = 0; -} +static struct rng_alg drbg_alg = { + .base.cra_name = "stdrng", + .base.cra_driver_name = "drbg_nopr_hmac_sha512", + .base.cra_priority = 201, + .base.cra_ctxsize = sizeof(struct drbg_state), + .base.cra_module = THIS_MODULE, + .base.cra_init = drbg_kcapi_init, + .set_ent = drbg_kcapi_set_entropy, + .seed = drbg_kcapi_seed, + .generate = drbg_kcapi_generate, + .base.cra_exit = drbg_kcapi_exit, +}; static int __init drbg_init(void) { - unsigned int i = 0; /* pointer to drbg_algs */ - unsigned int j = 0; /* pointer to drbg_cores */ int ret; ret = drbg_healthcheck_sanity(); if (ret) return ret; - if (ARRAY_SIZE(drbg_cores) * 2 > ARRAY_SIZE(drbg_algs)) { - pr_info("DRBG: Cannot register all DRBG types" - "(slots needed: %zu, slots available: %zu)\n", - ARRAY_SIZE(drbg_cores) * 2, ARRAY_SIZE(drbg_algs)); - return -EFAULT; - } - /* - * each DRBG definition can be used with PR and without PR, thus - * we instantiate each DRBG in drbg_cores[] twice. - * - * As the order of placing them into the drbg_algs array matters - * (the later DRBGs receive a higher cra_priority) we register the - * prediction resistance DRBGs first as the should not be too - * interesting. + * In FIPS mode, boost the algorithm priority to ensure that when users + * request "stdrng", they really get the algorithm from here. */ - for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++) - drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 1); - for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++) - drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 0); - return crypto_register_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); + if (fips_enabled) + drbg_alg.base.cra_priority += 2000; + + return crypto_register_rng(&drbg_alg); } static void __exit drbg_exit(void) { - crypto_unregister_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); + crypto_unregister_rng(&drbg_alg); } module_init(drbg_init); module_exit(drbg_exit); -#ifndef CRYPTO_DRBG_HASH_STRING -#define CRYPTO_DRBG_HASH_STRING "" -#endif -#ifndef CRYPTO_DRBG_HMAC_STRING -#define CRYPTO_DRBG_HMAC_STRING "" -#endif -#ifndef CRYPTO_DRBG_CTR_STRING -#define CRYPTO_DRBG_CTR_STRING "" -#endif MODULE_LICENSE("GPL"); MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); -MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG) " - "using following cores: " - CRYPTO_DRBG_HASH_STRING - CRYPTO_DRBG_HMAC_STRING - CRYPTO_DRBG_CTR_STRING); +MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG)"); MODULE_ALIAS_CRYPTO("stdrng"); -MODULE_IMPORT_NS("CRYPTO_INTERNAL"); +MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512"); diff --git a/crypto/ecc.c b/crypto/ecc.c index 43b0def3a225c..6eb4d97a5f0d3 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -393,14 +393,26 @@ static uint128_t mul_64_64(u64 left, u64 right) return result; } -static uint128_t add_128_128(uint128_t a, uint128_t b) +/* Calculate addition with overflow checking. Returns true on wrap-around, + * false otherwise. + */ +static bool check_add_128_128_overflow(uint128_t *result, uint128_t a, + uint128_t b) { - uint128_t result; + bool carry; - result.m_low = a.m_low + b.m_low; - result.m_high = a.m_high + b.m_high + (result.m_low < a.m_low); + result->m_low = a.m_low + b.m_low; + carry = (result->m_low < a.m_low); - return result; + result->m_high = a.m_high + b.m_high + carry; + + /* Using constant-time bitwise arithmetic to prevent timing + * side-channels. + */ + carry = (result->m_high < a.m_high) | + ((result->m_high == a.m_high) & carry); + + return carry; } static void vli_mult(u64 *result, const u64 *left, const u64 *right, @@ -425,9 +437,7 @@ static void vli_mult(u64 *result, const u64 *left, const u64 *right, uint128_t product; product = mul_64_64(left[i], right[k - i]); - - r01 = add_128_128(r01, product); - r2 += (r01.m_high < product.m_high); + r2 += check_add_128_128_overflow(&r01, r01, product); } result[k] = r01.m_low; @@ -450,7 +460,7 @@ static void vli_umult(u64 *result, const u64 *left, u32 right, uint128_t product; product = mul_64_64(left[k], right); - r01 = add_128_128(r01, product); + check_add_128_128_overflow(&r01, r01, product); /* no carry */ result[k] = r01.m_low; r01.m_low = r01.m_high; @@ -487,8 +497,7 @@ static void vli_square(u64 *result, const u64 *left, unsigned int ndigits) product.m_low <<= 1; } - r01 = add_128_128(r01, product); - r2 += (r01.m_high < product.m_high); + r2 += check_add_128_128_overflow(&r01, r01, product); } result[k] = r01.m_low; diff --git a/crypto/ecrdsa.c b/crypto/ecrdsa.c index 2c0602f0cd406..93c9e7d76792a 100644 --- a/crypto/ecrdsa.c +++ b/crypto/ecrdsa.c @@ -145,7 +145,7 @@ int ecrdsa_param_curve(void *context, size_t hdrlen, unsigned char tag, struct ecrdsa_ctx *ctx = context; ctx->curve_oid = look_up_OID(value, vlen); - if (!ctx->curve_oid) + if (ctx->curve_oid == OID__NR) return -EINVAL; ctx->curve = get_curve_by_oid(ctx->curve_oid); return 0; @@ -259,16 +259,11 @@ static unsigned int ecrdsa_max_size(struct crypto_sig *tfm) return 2 * ctx->pub_key.ndigits * sizeof(u64); } -static void ecrdsa_exit_tfm(struct crypto_sig *tfm) -{ -} - static struct sig_alg ecrdsa_alg = { .verify = ecrdsa_verify, .set_pub_key = ecrdsa_set_pub_key, .key_size = ecrdsa_key_size, .max_size = ecrdsa_max_size, - .exit = ecrdsa_exit_tfm, .base = { .cra_name = "ecrdsa", .cra_driver_name = "ecrdsa-generic", diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index d5832caa8ab3c..b024bff7024a8 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c @@ -7,7 +7,7 @@ * Design * ====== * - * See https://www.chronox.de/jent.html + * See https://www.chronox.de/jent/ * * License * ======= @@ -47,7 +47,7 @@ /* * This Jitterentropy RNG is based on the jitterentropy library - * version 3.4.0 provided at https://www.chronox.de/jent.html + * version 3.4.0 provided at https://www.chronox.de/jent/ */ #ifdef __OPTIMIZE__ @@ -775,7 +775,7 @@ int jent_entropy_init(unsigned int osr, unsigned int flags, * delta even when called shortly after each other -- this * implies that we also have a high resolution timer */ - if (!delta || (end_time == start_time)) { + if (!delta) { ret = JENT_ECOARSETIME; goto out; } diff --git a/crypto/kpp.c b/crypto/kpp.c index 7451d39a7ad8b..522c352a03afc 100644 --- a/crypto/kpp.c +++ b/crypto/kpp.c @@ -20,11 +20,9 @@ static int __maybe_unused crypto_kpp_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_kpp rkpp; - - memset(&rkpp, 0, sizeof(rkpp)); - - strscpy(rkpp.type, "kpp", sizeof(rkpp.type)); + struct crypto_report_kpp rkpp = { + .type = "kpp", + }; return nla_put(skb, CRYPTOCFGA_REPORT_KPP, sizeof(rkpp), &rkpp); } diff --git a/crypto/krb5/krb5_api.c b/crypto/krb5/krb5_api.c index c7ea40f900a77..03395b89cc61e 100644 --- a/crypto/krb5/krb5_api.c +++ b/crypto/krb5/krb5_api.c @@ -207,7 +207,7 @@ struct crypto_aead *krb5_prepare_encryption(const struct krb5_enctype *krb5, struct crypto_aead *ci = NULL; int ret = -ENOMEM; - ci = crypto_alloc_aead(krb5->encrypt_name, 0, 0); + ci = crypto_alloc_aead(krb5->encrypt_name, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(ci)) { ret = PTR_ERR(ci); if (ret == -ENOENT) diff --git a/crypto/lskcipher.c b/crypto/lskcipher.c index bb166250b7327..e4328df6e26c0 100644 --- a/crypto/lskcipher.c +++ b/crypto/lskcipher.c @@ -264,12 +264,10 @@ static int __maybe_unused crypto_lskcipher_report( struct sk_buff *skb, struct crypto_alg *alg) { struct lskcipher_alg *skcipher = __crypto_lskcipher_alg(alg); - struct crypto_report_blkcipher rblkcipher; - - memset(&rblkcipher, 0, sizeof(rblkcipher)); - - strscpy(rblkcipher.type, "lskcipher", sizeof(rblkcipher.type)); - strscpy(rblkcipher.geniv, "<none>", sizeof(rblkcipher.geniv)); + struct crypto_report_blkcipher rblkcipher = { + .type = "lskcipher", + .geniv = "<none>", + }; rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = skcipher->co.min_keysize; diff --git a/crypto/rng.c b/crypto/rng.c index 1d4b9177bad4d..eec786c45bdd8 100644 --- a/crypto/rng.c +++ b/crypto/rng.c @@ -65,11 +65,9 @@ static unsigned int seedsize(struct crypto_alg *alg) static int __maybe_unused crypto_rng_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_rng rrng; - - memset(&rrng, 0, sizeof(rrng)); - - strscpy(rrng.type, "rng", sizeof(rrng.type)); + struct crypto_report_rng rrng = { + .type = "rng", + }; rrng.seedsize = seedsize(alg); diff --git a/crypto/scompress.c b/crypto/scompress.c index 253655ece83fd..de54227203ce9 100644 --- a/crypto/scompress.c +++ b/crypto/scompress.c @@ -48,11 +48,9 @@ static DECLARE_WORK(scomp_scratch_work, scomp_scratch_workfn); static int __maybe_unused crypto_scomp_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_comp rscomp; - - memset(&rscomp, 0, sizeof(rscomp)); - - strscpy(rscomp.type, "scomp", sizeof(rscomp.type)); + struct crypto_report_comp rscomp = { + .type = "scomp", + }; return nla_put(skb, CRYPTOCFGA_REPORT_COMPRESS, sizeof(rscomp), &rscomp); diff --git a/crypto/shash.c b/crypto/shash.c index 351cba3c11070..d4a6c3b6fa372 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -333,12 +333,10 @@ static void crypto_shash_free_instance(struct crypto_instance *inst) static int __maybe_unused crypto_shash_report( struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_hash rhash; struct shash_alg *salg = __crypto_shash_alg(alg); - - memset(&rhash, 0, sizeof(rhash)); - - strscpy(rhash.type, "shash", sizeof(rhash.type)); + struct crypto_report_hash rhash = { + .type = "shash", + }; rhash.blocksize = alg->cra_blocksize; rhash.digestsize = salg->digestsize; diff --git a/crypto/sig.c b/crypto/sig.c index beba745b64057..7d2048da5c3af 100644 --- a/crypto/sig.c +++ b/crypto/sig.c @@ -53,9 +53,9 @@ static void __maybe_unused crypto_sig_show(struct seq_file *m, static int __maybe_unused crypto_sig_report(struct sk_buff *skb, struct crypto_alg *alg) { - struct crypto_report_sig rsig = {}; - - strscpy(rsig.type, "sig", sizeof(rsig.type)); + struct crypto_report_sig rsig = { + .type = "sig", + }; return nla_put(skb, CRYPTOCFGA_REPORT_SIG, sizeof(rsig), &rsig); } diff --git a/crypto/skcipher.c b/crypto/skcipher.c index 2b31d1d5d268b..617e840432b17 100644 --- a/crypto/skcipher.c +++ b/crypto/skcipher.c @@ -591,12 +591,10 @@ static int __maybe_unused crypto_skcipher_report( struct sk_buff *skb, struct crypto_alg *alg) { struct skcipher_alg *skcipher = __crypto_skcipher_alg(alg); - struct crypto_report_blkcipher rblkcipher; - - memset(&rblkcipher, 0, sizeof(rblkcipher)); - - strscpy(rblkcipher.type, "skcipher", sizeof(rblkcipher.type)); - strscpy(rblkcipher.geniv, "<none>", sizeof(rblkcipher.geniv)); + struct crypto_report_blkcipher rblkcipher = { + .type = "skcipher", + .geniv = "<none>", + }; rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = skcipher->min_keysize; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 4d86efae65b21..a3e80de91d4d6 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -28,13 +28,12 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/uio.h> -#include <crypto/rng.h> -#include <crypto/drbg.h> #include <crypto/akcipher.h> #include <crypto/kpp.h> #include <crypto/acompress.h> #include <crypto/sig.h> #include <crypto/internal/cipher.h> +#include <crypto/internal/rng.h> #include <crypto/internal/simd.h> #include "internal.h" @@ -3482,13 +3481,11 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, return err; } -static int drbg_cavs_test(const struct drbg_testvec *test, int pr, - const char *driver, u32 type, u32 mask) +static int drbg_cavs_test(const struct drbg_testvec *test, const char *driver, + u32 type, u32 mask) { int ret = -EAGAIN; struct crypto_rng *drng; - struct drbg_test_data test_data; - struct drbg_string addtl, pers, testentropy; unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL); if (!buf) @@ -3504,39 +3501,34 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr, return PTR_ERR(drng); } - test_data.testentropy = &testentropy; - drbg_string_fill(&testentropy, test->entropy, test->entropylen); - drbg_string_fill(&pers, test->pers, test->perslen); - ret = crypto_drbg_reset_test(drng, &pers, &test_data); + crypto_rng_set_entropy(drng, test->entropy, test->entropylen); + ret = crypto_rng_reset(drng, test->pers, test->perslen); if (ret) { - printk(KERN_ERR "alg: drbg: Failed to reset rng\n"); + printk(KERN_ERR "alg: drbg: Failed to instantiate rng\n"); goto outbuf; } - drbg_string_fill(&addtl, test->addtla, test->addtllen); - if (pr) { - drbg_string_fill(&testentropy, test->entpra, test->entprlen); - ret = crypto_drbg_get_bytes_addtl_test(drng, - buf, test->expectedlen, &addtl, &test_data); - } else { - ret = crypto_drbg_get_bytes_addtl(drng, - buf, test->expectedlen, &addtl); + if (test->ent_reseed_len) { + crypto_rng_set_entropy(drng, test->ent_reseed, + test->ent_reseed_len); + ret = crypto_rng_reset(drng, test->addtl_reseed, + test->addtl_reseed_len); + if (ret) { + printk(KERN_ERR "alg: drbg: Failed to reseed rng\n"); + goto outbuf; + } } + + ret = crypto_rng_generate(drng, test->addtla, test->addtllen, + buf, test->expectedlen); if (ret < 0) { printk(KERN_ERR "alg: drbg: could not obtain random data for " "driver %s\n", driver); goto outbuf; } - drbg_string_fill(&addtl, test->addtlb, test->addtllen); - if (pr) { - drbg_string_fill(&testentropy, test->entprb, test->entprlen); - ret = crypto_drbg_get_bytes_addtl_test(drng, - buf, test->expectedlen, &addtl, &test_data); - } else { - ret = crypto_drbg_get_bytes_addtl(drng, - buf, test->expectedlen, &addtl); - } + ret = crypto_rng_generate(drng, test->addtlb, test->addtllen, + buf, test->expectedlen); if (ret < 0) { printk(KERN_ERR "alg: drbg: could not obtain random data for " "driver %s\n", driver); @@ -3556,16 +3548,12 @@ static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { int err = 0; - int pr = 0; int i = 0; const struct drbg_testvec *template = desc->suite.drbg.vecs; unsigned int tcount = desc->suite.drbg.count; - if (0 == memcmp(driver, "drbg_pr_", 8)) - pr = 1; - for (i = 0; i < tcount; i++) { - err = drbg_cavs_test(&template[i], pr, driver, type, mask); + err = drbg_cavs_test(&template[i], driver, type, mask); if (err) { printk(KERN_ERR "alg: drbg: Test %d failed for %s\n", i, driver); @@ -4654,42 +4642,6 @@ static const struct alg_test_desc alg_test_descs[] = { .alg = "digest_null", .test = alg_test_null, }, { - .alg = "drbg_nopr_ctr_aes128", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_nopr_ctr_aes128_tv_template) - } - }, { - .alg = "drbg_nopr_ctr_aes192", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_nopr_ctr_aes192_tv_template) - } - }, { - .alg = "drbg_nopr_ctr_aes256", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_nopr_ctr_aes256_tv_template) - } - }, { - .alg = "drbg_nopr_hmac_sha256", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_nopr_hmac_sha256_tv_template) - } - }, { - /* - * There is no need to specifically test the DRBG with every - * backend cipher -- covered by drbg_nopr_hmac_sha512 test - */ - .alg = "drbg_nopr_hmac_sha384", - .test = alg_test_null, - .fips_allowed = 1 - }, { .alg = "drbg_nopr_hmac_sha512", .test = alg_test_drbg, .fips_allowed = 1, @@ -4697,70 +4649,6 @@ static const struct alg_test_desc alg_test_descs[] = { .drbg = __VECS(drbg_nopr_hmac_sha512_tv_template) } }, { - .alg = "drbg_nopr_sha256", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_nopr_sha256_tv_template) - } - }, { - /* covered by drbg_nopr_sha256 test */ - .alg = "drbg_nopr_sha384", - .test = alg_test_null, - .fips_allowed = 1 - }, { - .alg = "drbg_nopr_sha512", - .fips_allowed = 1, - .test = alg_test_null, - }, { - .alg = "drbg_pr_ctr_aes128", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_pr_ctr_aes128_tv_template) - } - }, { - /* covered by drbg_pr_ctr_aes128 test */ - .alg = "drbg_pr_ctr_aes192", - .fips_allowed = 1, - .test = alg_test_null, - }, { - .alg = "drbg_pr_ctr_aes256", - .fips_allowed = 1, - .test = alg_test_null, - }, { - .alg = "drbg_pr_hmac_sha256", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_pr_hmac_sha256_tv_template) - } - }, { - /* covered by drbg_pr_hmac_sha256 test */ - .alg = "drbg_pr_hmac_sha384", - .test = alg_test_null, - .fips_allowed = 1 - }, { - .alg = "drbg_pr_hmac_sha512", - .test = alg_test_null, - .fips_allowed = 1, - }, { - .alg = "drbg_pr_sha256", - .test = alg_test_drbg, - .fips_allowed = 1, - .suite = { - .drbg = __VECS(drbg_pr_sha256_tv_template) - } - }, { - /* covered by drbg_pr_sha256 test */ - .alg = "drbg_pr_sha384", - .test = alg_test_null, - .fips_allowed = 1 - }, { - .alg = "drbg_pr_sha512", - .fips_allowed = 1, - .test = alg_test_null, - }, { .alg = "ecb(aes)", .generic_driver = "ecb(aes-lib)", .test = alg_test_skcipher, @@ -5296,6 +5184,9 @@ static const struct alg_test_desc alg_test_descs[] = { .sig = __VECS(pkcs1_rsa_none_tv_template) } }, { + .alg = "pkcs1(rsa,sha1)", + .test = alg_test_null, + }, { .alg = "pkcs1(rsa,sha224)", .test = alg_test_null, .fips_allowed = 1, @@ -5331,6 +5222,9 @@ static const struct alg_test_desc alg_test_descs[] = { .test = alg_test_null, .fips_allowed = 1, }, { + .alg = "pkcs1pad(rsa,sha1)", + .test = alg_test_null, + }, { .alg = "rfc3686(ctr(aes))", .generic_driver = "rfc3686(ctr(aes-lib))", .test = alg_test_skcipher, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 9b4d7e11c9fd9..b7dcf40af6dbe 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -120,16 +120,24 @@ struct aead_testvec { }; struct drbg_testvec { + /* Instantiate */ const unsigned char *entropy; size_t entropylen; - const unsigned char *entpra; - const unsigned char *entprb; - size_t entprlen; + const unsigned char *pers; + size_t perslen; + + /* Reseed (optional) */ + const unsigned char *ent_reseed; + size_t ent_reseed_len; + const unsigned char *addtl_reseed; + size_t addtl_reseed_len; + + /* Generate (twice) */ const unsigned char *addtla; const unsigned char *addtlb; size_t addtllen; - const unsigned char *pers; - size_t perslen; + + /* Expected output from last call to Generate */ const unsigned char *expected; size_t expectedlen; }; @@ -23422,881 +23430,199 @@ static const struct aead_testvec aegis128_tv_template[] = { }, }; -/* - * SP800-90A DRBG Test vectors from - * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip - * - * Test vectors for DRBG with prediction resistance. All types of DRBGs - * (Hash, HMAC, CTR) are tested with all permutations of use cases (w/ and - * w/o personalization string, w/ and w/o additional input string). - */ -static const struct drbg_testvec drbg_pr_sha256_tv_template[] = { - { - .entropy = (unsigned char *) - "\x72\x88\x4c\xcd\x6c\x85\x57\x70\xf7\x0b\x8b\x86" - "\xc1\xeb\xd2\x4e\x36\x14\xab\x18\xc4\x9c\xc9\xcf" - "\x1a\xe8\xf7\x7b\x02\x49\x73\xd7\xf1\x42\x7d\xc6" - "\x3f\x29\x2d\xec\xd3\x66\x51\x3f\x1d\x8d\x5b\x4e", - .entropylen = 48, - .entpra = (unsigned char *) - "\x38\x9c\x91\xfa\xc2\xa3\x46\x89\x56\x08\x3f\x62" - "\x73\xd5\x22\xa9\x29\x63\x3a\x1d\xe5\x5d\x5e\x4f" - "\x67\xb0\x67\x7a\x5e\x9e\x0c\x62", - .entprb = (unsigned char *) - "\xb2\x8f\x36\xb2\xf6\x8d\x39\x13\xfa\x6c\x66\xcf" - "\x62\x8a\x7e\x8c\x12\x33\x71\x9c\x69\xe4\xa5\xf0" - "\x8c\xee\xeb\x9c\xf5\x31\x98\x31", - .entprlen = 32, - .expected = (unsigned char *) - "\x52\x7b\xa3\xad\x71\x77\xa4\x49\x42\x04\x61\xc7" - "\xf0\xaf\xa5\xfd\xd3\xb3\x0d\x6a\x61\xba\x35\x49" - "\xbb\xaa\xaf\xe4\x25\x7d\xb5\x48\xaf\x5c\x18\x3d" - "\x33\x8d\x9d\x45\xdf\x98\xd5\x94\xa8\xda\x92\xfe" - "\xc4\x3c\x94\x2a\xcf\x7f\x7b\xf2\xeb\x28\xa9\xf1" - "\xe0\x86\x30\xa8\xfe\xf2\x48\x90\x91\x0c\x75\xb5" - "\x3c\x00\xf0\x4d\x09\x4f\x40\xa7\xa2\x8c\x52\xdf" - "\x52\xef\x17\xbf\x3d\xd1\xa2\x31\xb4\xb8\xdc\xe6" - "\x5b\x0d\x1f\x78\x36\xb4\xe6\x4b\xa7\x11\x25\xd5" - "\x94\xc6\x97\x36\xab\xf0\xe5\x31\x28\x6a\xbb\xce" - "\x30\x81\xa6\x8f\x27\x14\xf8\x1c", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d" - "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0" - "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1" - "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6", - .entropylen = 48, - .entpra = (unsigned char *) - "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb" - "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13" - "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15", - .entprb = (unsigned char *) - "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09" - "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde" - "\x76\xaa\x55\x04\x8b\x0a\x72\x95", - .entprlen = 32, - .expected = (unsigned char *) - "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32" - "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c" - "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18" - "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb" - "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81" - "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4" - "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6" - "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13" - "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9" - "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60" - "\x50\x47\xa3\x63\x81\x16\xaf\x19", - .expectedlen = 128, - .addtla = (unsigned char *) - "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d" - "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad" - "\xa9\xd0\x1d\x59\x02\xc4\xff\x70", - .addtlb = (unsigned char *) - "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31" - "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41" - "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd", - .addtllen = 32, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\xc6\x1c\xaf\x83\xa2\x56\x38\xf9\xb0\xbc\xd9\x85" - "\xf5\x2e\xc4\x46\x9c\xe1\xb9\x40\x98\x70\x10\x72" - "\xd7\x7d\x15\x85\xa1\x83\x5a\x97\xdf\xc8\xa8\xe8" - "\x03\x4c\xcb\x70\x35\x8b\x90\x94\x46\x8a\x6e\xa1", - .entropylen = 48, - .entpra = (unsigned char *) - "\xc9\x05\xa4\xcf\x28\x80\x4b\x93\x0f\x8b\xc6\xf9" - "\x09\x41\x58\x74\xe9\xec\x28\xc7\x53\x0a\x73\x60" - "\xba\x0a\xde\x57\x5b\x4b\x9f\x29", - .entprb = (unsigned char *) - "\x4f\x31\xd2\xeb\xac\xfa\xa8\xe2\x01\x7d\xf3\xbd" - "\x42\xbd\x20\xa0\x30\x65\x74\xd5\x5d\xd2\xad\xa4" - "\xa9\xeb\x1f\x4d\xf6\xfd\xb8\x26", - .entprlen = 32, - .expected = (unsigned char *) - "\xf6\x13\x05\xcb\x83\x60\x16\x42\x49\x1d\xc6\x25" - "\x3b\x8c\x31\xa3\xbe\x8b\xbd\x1c\xe2\xec\x1d\xde" - "\xbb\xbf\xa1\xac\xa8\x9f\x50\xce\x69\xce\xef\xd5" - "\xd6\xf2\xef\x6a\xf7\x81\x38\xdf\xbc\xa7\x5a\xb9" - "\xb2\x42\x65\xab\xe4\x86\x8d\x2d\x9d\x59\x99\x2c" - "\x5a\x0d\x71\x55\x98\xa4\x45\xc2\x8d\xdb\x05\x5e" - "\x50\x21\xf7\xcd\xe8\x98\x43\xce\x57\x74\x63\x4c" - "\xf3\xb1\xa5\x14\x1e\x9e\x01\xeb\x54\xd9\x56\xae" - "\xbd\xb6\x6f\x1a\x47\x6b\x3b\x44\xe4\xa2\xe9\x3c" - "\x6c\x83\x12\x30\xb8\x78\x7f\x8e\x54\x82\xd4\xfe" - "\x90\x35\x0d\x4c\x4d\x85\xe7\x13", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\xa5\xbf\xac\x4f\x71\xa1\xbb\x67\x94\xc6\x50\xc7" - "\x2a\x45\x9e\x10\xa8\xed\xf7\x52\x4f\xfe\x21\x90" - "\xa4\x1b\xe1\xe2\x53\xcc\x61\x47", - .perslen = 32, - }, { - .entropy = (unsigned char *) - "\xb6\xc1\x8d\xdf\x99\x54\xbe\x95\x10\x48\xd9\xf6" - "\xd7\x48\xa8\x73\x2d\x74\xde\x1e\xde\x57\x7e\xf4" - "\x7b\x7b\x64\xef\x88\x7a\xa8\x10\x4b\xe1\xc1\x87" - "\xbb\x0b\xe1\x39\x39\x50\xaf\x68\x9c\xa2\xbf\x5e", - .entropylen = 48, - .entpra = (unsigned char *) - "\xdc\x81\x0a\x01\x58\xa7\x2e\xce\xee\x48\x8c\x7c" - "\x77\x9e\x3c\xf1\x17\x24\x7a\xbb\xab\x9f\xca\x12" - "\x19\xaf\x97\x2d\x5f\xf9\xff\xfc", - .entprb = (unsigned char *) - "\xaf\xfc\x4f\x98\x8b\x93\x95\xc1\xb5\x8b\x7f\x73" - "\x6d\xa6\xbe\x6d\x33\xeb\x2c\x82\xb1\xaf\xc1\xb6" - "\xb6\x05\xe2\x44\xaa\xfd\xe7\xdb", - .entprlen = 32, - .expected = (unsigned char *) - "\x51\x79\xde\x1c\x0f\x58\xf3\xf4\xc9\x57\x2e\x31" - "\xa7\x09\xa1\x53\x64\x63\xa2\xc5\x1d\x84\x88\x65" - "\x01\x1b\xc6\x16\x3c\x49\x5b\x42\x8e\x53\xf5\x18" - "\xad\x94\x12\x0d\x4f\x55\xcc\x45\x5c\x98\x0f\x42" - "\x28\x2f\x47\x11\xf9\xc4\x01\x97\x6b\xa0\x94\x50" - "\xa9\xd1\x5e\x06\x54\x3f\xdf\xbb\xc4\x98\xee\x8b" - "\xba\xa9\xfa\x49\xee\x1d\xdc\xfb\x50\xf6\x51\x9f" - "\x6c\x4a\x9a\x6f\x63\xa2\x7d\xad\xaf\x3a\x24\xa0" - "\xd9\x9f\x07\xeb\x15\xee\x26\xe0\xd5\x63\x39\xda" - "\x3c\x59\xd6\x33\x6c\x02\xe8\x05\x71\x46\x68\x44" - "\x63\x4a\x68\x72\xe9\xf5\x55\xfe", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x15\x20\x2f\xf6\x98\x28\x63\xa2\xc4\x4e\xbb\x6c" - "\xb2\x25\x92\x61\x79\xc9\x22\xc4\x61\x54\x96\xff" - "\x4a\x85\xca\x80\xfe\x0d\x1c\xd0", - .addtlb = (unsigned char *) - "\xde\x29\x8e\x03\x42\x61\xa3\x28\x5e\xc8\x80\xc2" - "\x6d\xbf\xad\x13\xe1\x8d\x2a\xc7\xe8\xc7\x18\x89" - "\x42\x58\x9e\xd6\xcc\xad\x7b\x1e", - .addtllen = 32, - .pers = (unsigned char *) - "\x84\xc3\x73\x9e\xce\xb3\xbc\x89\xf7\x62\xb3\xe1" - "\xd7\x48\x45\x8a\xa9\xcc\xe9\xed\xd5\x81\x84\x52" - "\x82\x4c\xdc\x19\xb8\xf8\x92\x5c", - .perslen = 32, - }, -}; - -static const struct drbg_testvec drbg_pr_hmac_sha256_tv_template[] = { - { - .entropy = (unsigned char *) - "\x99\x69\xe5\x4b\x47\x03\xff\x31\x78\x5b\x87\x9a" - "\x7e\x5c\x0e\xae\x0d\x3e\x30\x95\x59\xe9\xfe\x96" - "\xb0\x67\x6d\x49\xd5\x91\xea\x4d\x07\xd2\x0d\x46" - "\xd0\x64\x75\x7d\x30\x23\xca\xc2\x37\x61\x27\xab", - .entropylen = 48, - .entpra = (unsigned char *) - "\xc6\x0f\x29\x99\x10\x0f\x73\x8c\x10\xf7\x47\x92" - "\x67\x6a\x3f\xc4\xa2\x62\xd1\x37\x21\x79\x80\x46" - "\xe2\x9a\x29\x51\x81\x56\x9f\x54", - .entprb = (unsigned char *) - "\xc1\x1d\x45\x24\xc9\x07\x1b\xd3\x09\x60\x15\xfc" - "\xf7\xbc\x24\xa6\x07\xf2\x2f\xa0\x65\xc9\x37\x65" - "\x8a\x2a\x77\xa8\x69\x90\x89\xf4", - .entprlen = 32, - .expected = (unsigned char *) - "\xab\xc0\x15\x85\x60\x94\x80\x3a\x93\x8d\xff\xd2" - "\x0d\xa9\x48\x43\x87\x0e\xf9\x35\xb8\x2c\xfe\xc1" - "\x77\x06\xb8\xf5\x51\xb8\x38\x50\x44\x23\x5d\xd4" - "\x4b\x59\x9f\x94\xb3\x9b\xe7\x8d\xd4\x76\xe0\xcf" - "\x11\x30\x9c\x99\x5a\x73\x34\xe0\xa7\x8b\x37\xbc" - "\x95\x86\x23\x50\x86\xfa\x3b\x63\x7b\xa9\x1c\xf8" - "\xfb\x65\xef\xa2\x2a\x58\x9c\x13\x75\x31\xaa\x7b" - "\x2d\x4e\x26\x07\xaa\xc2\x72\x92\xb0\x1c\x69\x8e" - "\x6e\x01\xae\x67\x9e\xb8\x7c\x01\xa8\x9c\x74\x22" - "\xd4\x37\x2d\x6d\x75\x4a\xba\xbb\x4b\xf8\x96\xfc" - "\xb1\xcd\x09\xd6\x92\xd0\x28\x3f", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\xb9\x1f\xe9\xef\xdd\x9b\x7d\x20\xb6\xec\xe0\x2f" - "\xdb\x76\x24\xce\x41\xc8\x3a\x4a\x12\x7f\x3e\x2f" - "\xae\x05\x99\xea\xb5\x06\x71\x0d\x0c\x4c\xb4\x05" - "\x26\xc6\xbd\xf5\x7f\x2a\x3d\xf2\xb5\x49\x7b\xda", - .entropylen = 48, - .entpra = (unsigned char *) - "\xef\x67\x50\x9c\xa7\x7d\xdf\xb7\x2d\x81\x01\xa4" - "\x62\x81\x6a\x69\x5b\xb3\x37\x45\xa7\x34\x8e\x26" - "\x46\xd9\x26\xa2\x19\xd4\x94\x43", - .entprb = (unsigned char *) - "\x97\x75\x53\x53\xba\xb4\xa6\xb2\x91\x60\x71\x79" - "\xd1\x6b\x4a\x24\x9a\x34\x66\xcc\x33\xab\x07\x98" - "\x51\x78\x72\xb2\x79\xfd\x2c\xff", - .entprlen = 32, - .expected = (unsigned char *) - "\x9c\xdc\x63\x8a\x19\x23\x22\x66\x0c\xc5\xb9\xd7" - "\xfb\x2a\xb0\x31\xe3\x8a\x36\xa8\x5a\xa8\x14\xda" - "\x1e\xa9\xcc\xfe\xb8\x26\x44\x83\x9f\xf6\xff\xaa" - "\xc8\x98\xb8\x30\x35\x3b\x3d\x36\xd2\x49\xd4\x40" - "\x62\x0a\x65\x10\x76\x55\xef\xc0\x95\x9c\xa7\xda" - "\x3f\xcf\xb7\x7b\xc6\xe1\x28\x52\xfc\x0c\xe2\x37" - "\x0d\x83\xa7\x51\x4b\x31\x47\x3c\xe1\x3c\xae\x70" - "\x01\xc8\xa3\xd3\xc2\xac\x77\x9c\xd1\x68\x77\x9b" - "\x58\x27\x3b\xa5\x0f\xc2\x7a\x8b\x04\x65\x62\xd5" - "\xe8\xd6\xfe\x2a\xaf\xd3\xd3\xfe\xbd\x18\xfb\xcd" - "\xcd\x66\xb5\x01\x69\x66\xa0\x3c", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x17\xc1\x56\xcb\xcc\x50\xd6\x03\x7d\x45\x76\xa3" - "\x75\x76\xc1\x4a\x66\x1b\x2e\xdf\xb0\x2e\x7d\x56" - "\x6d\x99\x3b\xc6\x58\xda\x03\xf6", - .addtlb = (unsigned char *) - "\x7c\x7b\x4a\x4b\x32\x5e\x6f\x67\x34\xf5\x21\x4c" - "\xf9\x96\xf9\xbf\x1c\x8c\x81\xd3\x9b\x60\x6a\x44" - "\xc6\x03\xa2\xfb\x13\x20\x19\xb7", - .addtllen = 32, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" - "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" - "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" - "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", - .entropylen = 48, - .entpra = (unsigned char *) - "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" - "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" - "\x20\x28\xad\xf2\x60\xd7\xcd\x45", - .entprb = (unsigned char *) - "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" - "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" - "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", - .entprlen = 32, - .expected = (unsigned char *) - "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" - "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" - "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" - "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" - "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" - "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" - "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" - "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" - "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" - "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" - "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" - "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" - "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", - .perslen = 32, - }, { - .entropy = (unsigned char *) - "\xc7\xcc\xbc\x67\x7e\x21\x66\x1e\x27\x2b\x63\xdd" - "\x3a\x78\xdc\xdf\x66\x6d\x3f\x24\xae\xcf\x37\x01" - "\xa9\x0d\x89\x8a\xa7\xdc\x81\x58\xae\xb2\x10\x15" - "\x7e\x18\x44\x6d\x13\xea\xdf\x37\x85\xfe\x81\xfb", - .entropylen = 48, - .entpra = (unsigned char *) - "\x7b\xa1\x91\x5b\x3c\x04\xc4\x1b\x1d\x19\x2f\x1a" - "\x18\x81\x60\x3c\x6c\x62\x91\xb7\xe9\xf5\xcb\x96" - "\xbb\x81\x6a\xcc\xb5\xae\x55\xb6", - .entprb = (unsigned char *) - "\x99\x2c\xc7\x78\x7e\x3b\x88\x12\xef\xbe\xd3\xd2" - "\x7d\x2a\xa5\x86\xda\x8d\x58\x73\x4a\x0a\xb2\x2e" - "\xbb\x4c\x7e\xe3\x9a\xb6\x81\xc1", - .entprlen = 32, - .expected = (unsigned char *) - "\x95\x6f\x95\xfc\x3b\xb7\xfe\x3e\xd0\x4e\x1a\x14" - "\x6c\x34\x7f\x7b\x1d\x0d\x63\x5e\x48\x9c\x69\xe6" - "\x46\x07\xd2\x87\xf3\x86\x52\x3d\x98\x27\x5e\xd7" - "\x54\xe7\x75\x50\x4f\xfb\x4d\xfd\xac\x2f\x4b\x77" - "\xcf\x9e\x8e\xcc\x16\xa2\x24\xcd\x53\xde\x3e\xc5" - "\x55\x5d\xd5\x26\x3f\x89\xdf\xca\x8b\x4e\x1e\xb6" - "\x88\x78\x63\x5c\xa2\x63\x98\x4e\x6f\x25\x59\xb1" - "\x5f\x2b\x23\xb0\x4b\xa5\x18\x5d\xc2\x15\x74\x40" - "\x59\x4c\xb4\x1e\xcf\x9a\x36\xfd\x43\xe2\x03\xb8" - "\x59\x91\x30\x89\x2a\xc8\x5a\x43\x23\x7c\x73\x72" - "\xda\x3f\xad\x2b\xba\x00\x6b\xd1", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x18\xe8\x17\xff\xef\x39\xc7\x41\x5c\x73\x03\x03" - "\xf6\x3d\xe8\x5f\xc8\xab\xe4\xab\x0f\xad\xe8\xd6" - "\x86\x88\x55\x28\xc1\x69\xdd\x76", - .addtlb = (unsigned char *) - "\xac\x07\xfc\xbe\x87\x0e\xd3\xea\x1f\x7e\xb8\xe7" - "\x9d\xec\xe8\xe7\xbc\xf3\x18\x25\x77\x35\x4a\xaa" - "\x00\x99\x2a\xdd\x0a\x00\x50\x82", - .addtllen = 32, - .pers = (unsigned char *) - "\xbc\x55\xab\x3c\xf6\x52\xb0\x11\x3d\x7b\x90\xb8" - "\x24\xc9\x26\x4e\x5a\x1e\x77\x0d\x3d\x58\x4a\xda" - "\xd1\x81\xe9\xf8\xeb\x30\x8f\x6f", - .perslen = 32, - }, -}; - -static const struct drbg_testvec drbg_pr_ctr_aes128_tv_template[] = { - { - .entropy = (unsigned char *) - "\xd1\x44\xc6\x61\x81\x6d\xca\x9d\x15\x28\x8a\x42" - "\x94\xd7\x28\x9c\x43\x77\x19\x29\x1a\x6d\xc3\xa2", - .entropylen = 24, - .entpra = (unsigned char *) - "\x96\xd8\x9e\x45\x32\xc9\xd2\x08\x7a\x6d\x97\x15" - "\xb4\xec\x80\xb1", - .entprb = (unsigned char *) - "\x8b\xb6\x72\xb5\x24\x0b\x98\x65\x95\x95\xe9\xc9" - "\x28\x07\xeb\xc2", - .entprlen = 16, - .expected = (unsigned char *) - "\x70\x19\xd0\x4c\x45\x78\xd6\x68\xa9\x9a\xaa\xfe" - "\xc1\xdf\x27\x9a\x1c\x0d\x0d\xf7\x24\x75\x46\xcc" - "\x77\x6b\xdf\x89\xc6\x94\xdc\x74\x50\x10\x70\x18" - "\x9b\xdc\x96\xb4\x89\x23\x40\x1a\xce\x09\x87\xce" - "\xd2\xf3\xd5\xe4\x51\x67\x74\x11\x5a\xcc\x8b\x3b" - "\x8a\xf1\x23\xa8", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x8e\x83\xe0\xeb\x37\xea\x3e\x53\x5e\x17\x6e\x77" - "\xbd\xb1\x53\x90\xfc\xdc\xc1\x3c\x9a\x88\x22\x94", - .entropylen = 24, - .entpra = (unsigned char *) - "\x6a\x85\xe7\x37\xc8\xf1\x04\x31\x98\x4f\xc8\x73" - "\x67\xd1\x08\xf8", - .entprb = (unsigned char *) - "\xd7\xa4\x68\xe2\x12\x74\xc3\xd9\xf1\xb7\x05\xbc" - "\xd4\xba\x04\x58", - .entprlen = 16, - .expected = (unsigned char *) - "\x78\xd6\xa6\x70\xff\xd1\x82\xf5\xa2\x88\x7f\x6d" - "\x3d\x8c\x39\xb1\xa8\xcb\x2c\x91\xab\x14\x7e\xbc" - "\x95\x45\x9f\x24\xb8\x20\xac\x21\x23\xdb\x72\xd7" - "\x12\x8d\x48\x95\xf3\x19\x0c\x43\xc6\x19\x45\xfc" - "\x8b\xac\x40\x29\x73\x00\x03\x45\x5e\x12\xff\x0c" - "\xc1\x02\x41\x82", - .expectedlen = 64, - .addtla = (unsigned char *) - "\xa2\xd9\x38\xcf\x8b\x29\x67\x5b\x65\x62\x6f\xe8" - "\xeb\xb3\x01\x76", - .addtlb = (unsigned char *) - "\x59\x63\x1e\x81\x8a\x14\xa8\xbb\xa1\xb8\x41\x25" - "\xd0\x7f\xcc\x43", - .addtllen = 16, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x04\xd9\x49\xa6\xdc\xe8\x6e\xbb\xf1\x08\x77\x2b" - "\x9e\x08\xca\x92\x65\x16\xda\x99\xa2\x59\xf3\xe8", - .entropylen = 24, - .entpra = (unsigned char *) - "\x38\x7e\x3f\x6b\x51\x70\x7b\x20\xec\x53\xd0\x66" - "\xc3\x0f\xe3\xb0", - .entprb = (unsigned char *) - "\xe0\x86\xa6\xaa\x5f\x72\x2f\xad\xf7\xef\x06\xb8" - "\xd6\x9c\x9d\xe8", - .entprlen = 16, - .expected = (unsigned char *) - "\xc9\x0a\xaf\x85\x89\x71\x44\x66\x4f\x25\x0b\x2b" - "\xde\xd8\xfa\xff\x52\x5a\x1b\x32\x5e\x41\x7a\x10" - "\x1f\xef\x1e\x62\x23\xe9\x20\x30\xc9\x0d\xad\x69" - "\xb4\x9c\x5b\xf4\x87\x42\xd5\xae\x5e\x5e\x43\xcc" - "\xd9\xfd\x0b\x93\x4a\xe3\xd4\x06\x37\x36\x0f\x3f" - "\x72\x82\x0c\xcf", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\xbf\xa4\x9a\x8f\x7b\xd8\xb1\x7a\x9d\xfa\x45\xed" - "\x21\x52\xb3\xad", - .perslen = 16, - }, { - .entropy = (unsigned char *) - "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06" - "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97", - .entropylen = 24, - .entpra = (unsigned char *) - "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7" - "\xc4\x2c\xe8\x10", - .entprb = (unsigned char *) - "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22" - "\x08\xf7\xa5\x01", - .entprlen = 16, - .expected = (unsigned char *) - "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71" - "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28" - "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45" - "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08" - "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4" - "\x23\xc5\x1f\x68", - .expectedlen = 64, - .addtla = (unsigned char *) - "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59" - "\x23\x6d\xad\x1d", - .addtlb = (unsigned char *) - "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12" - "\xbc\x59\x31\x8c", - .addtllen = 16, - .pers = (unsigned char *) - "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4" - "\x37\x3c\x5c\x0b", - .perslen = 16, - }, -}; - -/* - * SP800-90A DRBG Test vectors from - * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip - * - * Test vectors for DRBG without prediction resistance. All types of DRBGs - * (Hash, HMAC, CTR) are tested with all permutations of use cases (w/ and - * w/o personalization string, w/ and w/o additional input string). - */ -static const struct drbg_testvec drbg_nopr_sha256_tv_template[] = { - { - .entropy = (unsigned char *) - "\xa6\x5a\xd0\xf3\x45\xdb\x4e\x0e\xff\xe8\x75\xc3" - "\xa2\xe7\x1f\x42\xc7\x12\x9d\x62\x0f\xf5\xc1\x19" - "\xa9\xef\x55\xf0\x51\x85\xe0\xfb\x85\x81\xf9\x31" - "\x75\x17\x27\x6e\x06\xe9\x60\x7d\xdb\xcb\xcc\x2e", - .entropylen = 48, - .expected = (unsigned char *) - "\xd3\xe1\x60\xc3\x5b\x99\xf3\x40\xb2\x62\x82\x64" - "\xd1\x75\x10\x60\xe0\x04\x5d\xa3\x83\xff\x57\xa5" - "\x7d\x73\xa6\x73\xd2\xb8\xd8\x0d\xaa\xf6\xa6\xc3" - "\x5a\x91\xbb\x45\x79\xd7\x3f\xd0\xc8\xfe\xd1\x11" - "\xb0\x39\x13\x06\x82\x8a\xdf\xed\x52\x8f\x01\x81" - "\x21\xb3\xfe\xbd\xc3\x43\xe7\x97\xb8\x7d\xbb\x63" - "\xdb\x13\x33\xde\xd9\xd1\xec\xe1\x77\xcf\xa6\xb7" - "\x1f\xe8\xab\x1d\xa4\x66\x24\xed\x64\x15\xe5\x1c" - "\xcd\xe2\xc7\xca\x86\xe2\x83\x99\x0e\xea\xeb\x91" - "\x12\x04\x15\x52\x8b\x22\x95\x91\x02\x81\xb0\x2d" - "\xd4\x31\xf4\xc9\xf7\x04\x27\xdf", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c" - "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d" - "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff" - "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56", - .entropylen = 48, - .expected = (unsigned char *) - "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7" - "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b" - "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0" - "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8" - "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f" - "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d" - "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59" - "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b" - "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0" - "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c" - "\x70\xa8\x07\x59\x97\xeb\xf6\xbe", - .expectedlen = 128, - .addtla = (unsigned char *) - "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73" - "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10" - "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd", - .addtlb = (unsigned char *) - "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0" - "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d" - "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40", - .addtllen = 32, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x2a\x85\xa9\x8b\xd0\xda\x83\xd6\xad\xab\x9f\xbb" - "\x54\x31\x15\x95\x1c\x4d\x49\x9f\x6a\x15\xf6\xe4" - "\x15\x50\x88\x06\x29\x0d\xed\x8d\xb9\x6f\x96\xe1" - "\x83\x9f\xf7\x88\xda\x84\xbf\x44\x28\xd9\x1d\xaa", - .entropylen = 48, - .expected = (unsigned char *) - "\x2d\x55\xde\xc9\xed\x05\x47\x07\x3d\x04\xfc\x28" - "\x0f\x92\xf0\x4d\xd8\x00\x32\x47\x0a\x1b\x1c\x4b" - "\xef\xd9\x97\xa1\x17\x67\xda\x26\x6c\xfe\x76\x46" - "\x6f\xbc\x6d\x82\x4e\x83\x8a\x98\x66\x6c\x01\xb6" - "\xe6\x64\xe0\x08\x10\x6f\xd3\x5d\x90\xe7\x0d\x72" - "\xa6\xa7\xe3\xbb\x98\x11\x12\x56\x23\xc2\x6d\xd1" - "\xc8\xa8\x7a\x39\xf3\x34\xe3\xb8\xf8\x66\x00\x77" - "\x7d\xcf\x3c\x3e\xfa\xc9\x0f\xaf\xe0\x24\xfa\xe9" - "\x84\xf9\x6a\x01\xf6\x35\xdb\x5c\xab\x2a\xef\x4e" - "\xac\xab\x55\xb8\x9b\xef\x98\x68\xaf\x51\xd8\x16" - "\xa5\x5e\xae\xf9\x1e\xd2\xdb\xe6", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\xa8\x80\xec\x98\x30\x98\x15\xd2\xc6\xc4\x68\xf1" - "\x3a\x1c\xbf\xce\x6a\x40\x14\xeb\x36\x99\x53\xda" - "\x57\x6b\xce\xa4\x1c\x66\x3d\xbc", - .perslen = 32, - }, { - .entropy = (unsigned char *) - "\x69\xed\x82\xa9\xc5\x7b\xbf\xe5\x1d\x2f\xcb\x7a" - "\xd3\x50\x7d\x96\xb4\xb9\x2b\x50\x77\x51\x27\x74" - "\x33\x74\xba\xf1\x30\xdf\x8e\xdf\x87\x1d\x87\xbc" - "\x96\xb2\xc3\xa7\xed\x60\x5e\x61\x4e\x51\x29\x1a", - .entropylen = 48, - .expected = (unsigned char *) - "\xa5\x71\x24\x31\x11\xfe\x13\xe1\xa8\x24\x12\xfb" - "\x37\xa1\x27\xa5\xab\x77\xa1\x9f\xae\x8f\xaf\x13" - "\x93\xf7\x53\x85\x91\xb6\x1b\xab\xd4\x6b\xea\xb6" - "\xef\xda\x4c\x90\x6e\xef\x5f\xde\xe1\xc7\x10\x36" - "\xd5\x67\xbd\x14\xb6\x89\x21\x0c\xc9\x92\x65\x64" - "\xd0\xf3\x23\xe0\x7f\xd1\xe8\x75\xc2\x85\x06\xea" - "\xca\xc0\xcb\x79\x2d\x29\x82\xfc\xaa\x9a\xc6\x95" - "\x7e\xdc\x88\x65\xba\xec\x0e\x16\x87\xec\xa3\x9e" - "\xd8\x8c\x80\xab\x3a\x64\xe0\xcb\x0e\x45\x98\xdd" - "\x7c\x6c\x6c\x26\x11\x13\xc8\xce\xa9\x47\xa6\x06" - "\x57\xa2\x66\xbb\x2d\x7f\xf3\xc1", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x74\xd3\x6d\xda\xe8\xd6\x86\x5f\x63\x01\xfd\xf2" - "\x7d\x06\x29\x6d\x94\xd1\x66\xf0\xd2\x72\x67\x4e" - "\x77\xc5\x3d\x9e\x03\xe3\xa5\x78", - .addtlb = (unsigned char *) - "\xf6\xb6\x3d\xf0\x7c\x26\x04\xc5\x8b\xcd\x3e\x6a" - "\x9f\x9c\x3a\x2e\xdb\x47\x87\xe5\x8e\x00\x5e\x2b" - "\x74\x7f\xa6\xf6\x80\xcd\x9b\x21", - .addtllen = 32, - .pers = (unsigned char *) - "\x74\xa6\xe0\x08\xf9\x27\xee\x1d\x6e\x3c\x28\x20" - "\x87\xdd\xd7\x54\x31\x47\x78\x4b\xe5\x6d\xa3\x73" - "\xa9\x65\xb1\x10\xc1\xdc\x77\x7c", - .perslen = 32, - }, -}; - -static const struct drbg_testvec drbg_nopr_hmac_sha256_tv_template[] = { - { - .entropy = (unsigned char *) - "\xca\x85\x19\x11\x34\x93\x84\xbf\xfe\x89\xde\x1c" - "\xbd\xc4\x6e\x68\x31\xe4\x4d\x34\xa4\xfb\x93\x5e" - "\xe2\x85\xdd\x14\xb7\x1a\x74\x88\x65\x9b\xa9\x6c" - "\x60\x1d\xc6\x9f\xc9\x02\x94\x08\x05\xec\x0c\xa8", - .entropylen = 48, - .expected = (unsigned char *) - "\xe5\x28\xe9\xab\xf2\xde\xce\x54\xd4\x7c\x7e\x75" - "\xe5\xfe\x30\x21\x49\xf8\x17\xea\x9f\xb4\xbe\xe6" - "\xf4\x19\x96\x97\xd0\x4d\x5b\x89\xd5\x4f\xbb\x97" - "\x8a\x15\xb5\xc4\x43\xc9\xec\x21\x03\x6d\x24\x60" - "\xb6\xf7\x3e\xba\xd0\xdc\x2a\xba\x6e\x62\x4a\xbf" - "\x07\x74\x5b\xc1\x07\x69\x4b\xb7\x54\x7b\xb0\x99" - "\x5f\x70\xde\x25\xd6\xb2\x9e\x2d\x30\x11\xbb\x19" - "\xd2\x76\x76\xc0\x71\x62\xc8\xb5\xcc\xde\x06\x68" - "\x96\x1d\xf8\x68\x03\x48\x2c\xb3\x7e\xd6\xd5\xc0" - "\xbb\x8d\x50\xcf\x1f\x50\xd4\x76\xaa\x04\x58\xbd" - "\xab\xa8\x06\xf4\x8b\xe9\xdc\xb8", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\xf9\x7a\x3c\xfd\x91\xfa\xa0\x46\xb9\xe6\x1b\x94" - "\x93\xd4\x36\xc4\x93\x1f\x60\x4b\x22\xf1\x08\x15" - "\x21\xb3\x41\x91\x51\xe8\xff\x06\x11\xf3\xa7\xd4" - "\x35\x95\x35\x7d\x58\x12\x0b\xd1\xe2\xdd\x8a\xed", - .entropylen = 48, - .expected = (unsigned char *) - "\xc6\x87\x1c\xff\x08\x24\xfe\x55\xea\x76\x89\xa5" - "\x22\x29\x88\x67\x30\x45\x0e\x5d\x36\x2d\xa5\xbf" - "\x59\x0d\xcf\x9a\xcd\x67\xfe\xd4\xcb\x32\x10\x7d" - "\xf5\xd0\x39\x69\xa6\x6b\x1f\x64\x94\xfd\xf5\xd6" - "\x3d\x5b\x4d\x0d\x34\xea\x73\x99\xa0\x7d\x01\x16" - "\x12\x6d\x0d\x51\x8c\x7c\x55\xba\x46\xe1\x2f\x62" - "\xef\xc8\xfe\x28\xa5\x1c\x9d\x42\x8e\x6d\x37\x1d" - "\x73\x97\xab\x31\x9f\xc7\x3d\xed\x47\x22\xe5\xb4" - "\xf3\x00\x04\x03\x2a\x61\x28\xdf\x5e\x74\x97\xec" - "\xf8\x2c\xa7\xb0\xa5\x0e\x86\x7e\xf6\x72\x8a\x4f" - "\x50\x9a\x8c\x85\x90\x87\x03\x9c", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x51\x72\x89\xaf\xe4\x44\xa0\xfe\x5e\xd1\xa4\x1d" - "\xbb\xb5\xeb\x17\x15\x00\x79\xbd\xd3\x1e\x29\xcf" - "\x2f\xf3\x00\x34\xd8\x26\x8e\x3b", - .addtlb = (unsigned char *) - "\x88\x02\x8d\x29\xef\x80\xb4\xe6\xf0\xfe\x12\xf9" - "\x1d\x74\x49\xfe\x75\x06\x26\x82\xe8\x9c\x57\x14" - "\x40\xc0\xc9\xb5\x2c\x42\xa6\xe0", - .addtllen = 32, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" - "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" - "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" - "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", - .entropylen = 48, - .expected = (unsigned char *) - "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" - "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" - "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" - "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" - "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" - "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" - "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" - "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" - "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" - "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" - "\x10\x37\x41\x03\x0c\xcc\x3a\x56", - .expectedlen = 128, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" - "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" - "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", - .perslen = 32, - }, { - .entropy = (unsigned char *) - "\xc2\xa5\x66\xa9\xa1\x81\x7b\x15\xc5\xc3\xb7\x78" - "\x17\x7a\xc8\x7c\x24\xe7\x97\xbe\x0a\x84\x5f\x11" - "\xc2\xfe\x39\x9d\xd3\x77\x32\xf2\xcb\x18\x94\xeb" - "\x2b\x97\xb3\xc5\x6e\x62\x83\x29\x51\x6f\x86\xec", - .entropylen = 48, - .expected = (unsigned char *) - "\xb3\xa3\x69\x8d\x77\x76\x99\xa0\xdd\x9f\xa3\xf0" - "\xa9\xfa\x57\x83\x2d\x3c\xef\xac\x5d\xf2\x44\x37" - "\xc6\xd7\x3a\x0f\xe4\x10\x40\xf1\x72\x90\x38\xae" - "\xf1\xe9\x26\x35\x2e\xa5\x9d\xe1\x20\xbf\xb7\xb0" - "\x73\x18\x3a\x34\x10\x6e\xfe\xd6\x27\x8f\xf8\xad" - "\x84\x4b\xa0\x44\x81\x15\xdf\xdd\xf3\x31\x9a\x82" - "\xde\x6b\xb1\x1d\x80\xbd\x87\x1a\x9a\xcd\x35\xc7" - "\x36\x45\xe1\x27\x0f\xb9\xfe\x4f\xa8\x8e\xc0\xe4" - "\x65\x40\x9e\xa0\xcb\xa8\x09\xfe\x2f\x45\xe0\x49" - "\x43\xa2\xe3\x96\xbb\xb7\xdd\x2f\x4e\x07\x95\x30" - "\x35\x24\xcc\x9c\xc5\xea\x54\xa1", - .expectedlen = 128, - .addtla = (unsigned char *) - "\x41\x3d\xd8\x3f\xe5\x68\x35\xab\xd4\x78\xcb\x96" - "\x93\xd6\x76\x35\x90\x1c\x40\x23\x9a\x26\x64\x62" - "\xd3\x13\x3b\x83\xe4\x9c\x82\x0b", - .addtlb = (unsigned char *) - "\xd5\xc4\xa7\x1f\x9d\x6d\x95\xa1\xbe\xdf\x0b\xd2" - "\x24\x7c\x27\x7d\x1f\x84\xa4\xe5\x7a\x4a\x88\x25" - "\xb8\x2a\x2d\x09\x7d\xe6\x3e\xf1", - .addtllen = 32, - .pers = (unsigned char *) - "\x13\xce\x4d\x8d\xd2\xdb\x97\x96\xf9\x41\x56\xc8" - "\xe8\xf0\x76\x9b\x0a\xa1\xc8\x2c\x13\x23\xb6\x15" - "\x36\x60\x3b\xca\x37\xc9\xee\x29", - .perslen = 32, - }, -}; - -/* Test vector obtained during NIST ACVP testing */ static const struct drbg_testvec drbg_nopr_hmac_sha512_tv_template[] = { + /* + * Borrowed from the first applicable test vector from ACVP: + * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/prompt.json#L4596 + * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/expectedResults.json#L986 + */ { - .entropy = (unsigned char *) - "\xDF\xB0\xF2\x18\xF0\x78\x07\x01\x29\xA4\x29\x26" - "\x2F\x8A\x34\xCB\x37\xEF\xEE\x41\xE6\x96\xF7\xFF" - "\x61\x47\xD3\xED\x41\x97\xEF\x64\x0C\x48\x56\x5A" - "\xE6\x40\x6E\x4A\x3B\x9E\x7F\xAC\x08\xEC\x25\xAE" - "\x0B\x51\x0E\x2C\x44\x2E\xBD\xDB\x57\xD0\x4A\x6D" - "\x80\x3E\x37\x0F", - .entropylen = 64, - .expected = (unsigned char *) - "\x48\xc6\xa8\xdb\x09\xae\xde\x5d\x8c\x77\xf3\x52" - "\x92\x71\xa7\xb9\x6d\x53\x6d\xa3\x73\xe3\x55\xb8" - "\x39\xd6\x44\x2b\xee\xcb\xe1\x32\x15\x30\xbe\x4e" - "\x9b\x1e\x06\xd1\x6b\xbf\xd5\x3e\xea\x7c\xf5\xaa" - "\x4b\x05\xb5\xd3\xa7\xb2\xc4\xfe\xe7\x1b\xda\x11" - "\x43\x98\x03\x70\x90\xbf\x6e\x43\x9b\xe4\x14\xef" - "\x71\xa3\x2a\xef\x9f\x0d\xb9\xe3\x52\xf2\x89\xc9" - "\x66\x9a\x60\x60\x99\x60\x62\x4c\xd6\x45\x52\x54" - "\xe6\x32\xb2\x1b\xd4\x48\xb5\xa6\xf9\xba\xd3\xff" - "\x29\xc5\x21\xe0\x91\x31\xe0\x38\x8c\x93\x0f\x3c" - "\x30\x7b\x53\xa3\xc0\x7f\x2d\xc1\x39\xec\x69\x0e" - "\xf2\x4a\x3c\x65\xcc\xed\x07\x2a\xf2\x33\x83\xdb" - "\x10\x74\x96\x40\xa7\xc5\x1b\xde\x81\xca\x0b\x8f" - "\x1e\x0a\x1a\x7a\xbf\x3c\x4a\xb8\x8c\xaf\x7b\x80" - "\xb7\xdc\x5d\x0f\xef\x1b\x97\x6e\x3d\x17\x23\x5a" - "\x31\xb9\x19\xcf\x5a\xc5\x00\x2a\xb6\xf3\x99\x34" - "\x65\xee\xe9\x1c\x55\xa0\x3b\x07\x60\xc9\xc4\xe4" - "\xf7\x57\x5c\x34\x9f\xc6\x31\x30\x3f\x23\xb2\x89" - "\xc0\xe7\x50\xf3\xde\x59\xd1\x0e\xb3\x0f\x78\xcc" - "\x7e\x54\x5e\x61\xf6\x86\x3d\xb3\x11\x94\x36\x3e" - "\x61\x5c\x48\x99\xf6\x7b\x02\x9a\xdc\x6a\x28\xe6" - "\xd1\xa7\xd1\xa3", - .expectedlen = 256, - .addtla = (unsigned char *) - "\x6B\x0F\x4A\x48\x0B\x12\x85\xE4\x72\x23\x7F\x7F" - "\x94\x7C\x24\x69\x14\x9F\xDC\x72\xA6\x33\xAD\x3C" - "\x8C\x72\xC1\x88\x49\x59\x82\xC5", - .addtlb = (unsigned char *) - "\xC4\xAF\x36\x3D\xB8\x5D\x9D\xFA\x92\xF5\xC3\x3C" - "\x2D\x1E\x22\x2A\xBD\x8B\x05\x6F\xA3\xFC\xBF\x16" - "\xED\xAA\x75\x8D\x73\x9A\xF6\xEC", - .addtllen = 32, - .pers = NULL, - .perslen = 0, - } -}; + /* .entropy = ACVP entropyInput || nonce */ + .entropy = "\x47\x28\x33\x05\x82\xE8\xA7\x58\x05\xBD\x07\x9E" + "\xDB\x59\x87\x08\x3B\x82\x40\x70\xA1\xB7\x33\x4F" + "\x0F\x53\xBE\xF6\x98\x75\xFA\x21\x00\x04\xBC\x58" + "\x9B\xB1\xB3\xBC\x2A\xF6\xA4\x2A\xE1\xB3\x65\x24" + "\xA8\xEE\x56\x70\x5E\x28\x06\x04\x80\xCE\xB7\x36" + "\xA4\xD1\x4E\xAA\xE7\xE8\x51\x40\x7D\x30\xF7\x91" + "\xF2\x9E\x98\xA7\xBB\xB3\x1D\xC6\x8A\x62\xC7\xE7" + "\x1F\xE1\x0A\x52\x45\x39\x88\x92\x43\xA6\x5B\xC3" + "\x9D\x60\xDE\xFE\x79\xEF\x87\x6F\xD5\x76\x51\x69" + "\x7B\x4C\x3D\x08\x60\xFA\xDC\x00\x94\xEC\x0A\xC5" + "\xE7\xCB\x30\x05\x9F\xCC\x07\x44\x07\x14\xF4\xF9" + "\xBC\x7D\xC0\x66\x63\x5B\xD3\x2A\xA7\xF2\x1D\x75" + "\x3F\x28\x5F\x4A\xEB\x63\xD7\x92\x5A\x9A\x7C\x3A" + "\x56\xEA\xCB\xA9\xA0\xF9\x5B\x99\xC2\x7D\x31\xBF" + "\x44\xC7\x64\x6B\x7E\x64\x60\x64\x05\x86\xF0\x6B" + "\x76\xA7\x3E\x63\xAD\xB6\x76\xED\x3D\x05\x2E\xC7" + "\xC7\x52\x8F\x07\x56\x23\xFC\x2F\x93\xD5\xF2\x29" + "\xC6\x84\x48\xD1\x88\xB9\x3F\x84\xB2\x93\xFC\x2F" + "\x00\xB1\xBC\xBE\xAC\xC4\x94\x36\xF1\x2B\xF0\xC7" + "\x36\xE8\x1D\x45\x0A\xA2\xFE\x72\xD7\x3E\x15\x6A" + "\x74\x23\xB2\xD1\x3C\x20\xF2\xB7\x19\xC5\xF0\x74" + "\x69\x06\xD1\x92\x47\xC9\x68\xDC\xEE\xBC\xF4\x3A" + "\x8B\x7C\xA4\xA4\x4A\x15\xF4\xF0\x26\x26\xC5\x7D" + "\x57\xDC\x00\x59\x07\xDF\x84\x2A\x23\xA9\xC1\xAF" + "\x47\x49\x88\xCC\x2F\x3B\x90\x39\xA0\x09\xAE\x3C" + "\x79\xF9\x97\x9D\xEF\x13\x1D\x2B\xB6\x18\xDB\xCF" + "\x95\x98\x17\x7F\xF6\x95\x44\x3A\x40\x90\x63\x16" + "\x70\x38\x22\xC5\xD8\xE4\x57\xA0\x8E\x51\x6B\xED" + "\x03\x18\xC6\x74\xFA\xCA\xF2\xD5\xB2\x5A\x0C\x02" + "\x48\x9F\x70\x0B\x1C\x0A\xD1\xD6\x4F\x3F\x70\x3C" + "\x1A\x62\x29\x63\xD0\x92\x76\x30\x7C\xB9\x54\xEC" + "\xF6\x92\xA3\x11\x66\xB2\x56\xE0\x75\x3D\x27\x01", + .entropylen = 384, + .pers = "\x03\x75\x33\x7B\x6B\xE5\x14\xAF\x0E\x43\x33\xCC\xD3" + "\xF4\xF0\x8B\x8A\xCC\xFE\x95\xC1\x20\xB9\x56\x3D\x2C" + "\x34\xC7\xA1\x4C\xBC\xDC\x0A\x8D\xBE\x68\x28\x89\x2A" + "\x92\x10\x05\x4E\xF9\xE2\x51\xF7\x4F\xF4\x48\x76\xC9" + "\xCE\xA8\x6D\xC1\xDE\x5C\x05\x95\x77\x24\xB4\x5D\x3D" + "\x16\x1D\xCB\x43\xE5\xD3\x01\x96\xCC\x3E\x2E\xE1\x97" + "\xB3\x42\xC2\xAB\xEC\x56\xA9\xF9\xF2\x28\x59\x01\x4E" + "\xFC\x8A\xC0\x5E\x4E\x33\x30\x91\x96\x93\xBA\xFA\xE1" + "\x9F\x20\xC3\xC1\xD1\xC6\xC3\x2C\x59\x8F\x56\xD5\x73" + "\xE8\x8D\xCF\xAC\xB1\x85\x3E\xC7\x73\x21\x59\x8D\x0F" + "\xF4\xA4\xC4\x0C\xD2\x18\x81\x5F\x3E\x37\xC9\x9F\xD9" + "\xDE\x3F\x15\x6F\xAC\x1A\xEC\x5E\x28\xD5\x56\xA2\x65" + "\xD2\x7C\x41\xDE\x57\x8C\x60\xAB\xA5\x03\x42\xC8\x3C" + "\x70\xC2\xD1\x11\x62\x25\x4E\x17\x58\xBB\x08\x51\x79" + "\xE6\xED\xBA\x9A\xA7\x07\xD5\x0E\x89\x43\x31\x4F\x99" + "\xEE\xED\xF1\x36\xFA\x1E\xC0\x25\x01\xDA\x19\xC2\x7D" + "\x5D\x78\x74\x5C\xC0\x72\x2E\xF1\x7B\x4E\x9C\xDB\xFE" + "\x60\x89\x62\x71\x9C\xEA\xD3\xDF\x82\xC7\x8B\xB4\x7B" + "\x7B\x7F\x6A\x62\x3C\x57\x76\xA5\x67\x5F\x70\xFB\xE0" + "\x1B\x23\x79\x71\xB5\x7C\xEA\x76\x99", + .perslen = 256, -static const struct drbg_testvec drbg_nopr_ctr_aes192_tv_template[] = { - { - .entropy = (unsigned char *) - "\xc3\x5c\x2f\xa2\xa8\x9d\x52\xa1\x1f\xa3\x2a\xa9" - "\x6c\x95\xb8\xf1\xc9\xa8\xf9\xcb\x24\x5a\x8b\x40" - "\xf3\xa6\xe5\xa7\xfb\xd9\xd3\xc6\x8e\x27\x7b\xa9" - "\xac\x9b\xbb\x00", - .entropylen = 40, - .expected = (unsigned char *) - "\x8c\x2e\x72\xab\xfd\x9b\xb8\x28\x4d\xb7\x9e\x17" - "\xa4\x3a\x31\x46\xcd\x76\x94\xe3\x52\x49\xfc\x33" - "\x83\x91\x4a\x71\x17\xf4\x13\x68\xe6\xd4\xf1\x48" - "\xff\x49\xbf\x29\x07\x6b\x50\x15\xc5\x9f\x45\x79" - "\x45\x66\x2e\x3d\x35\x03\x84\x3f\x4a\xa5\xa3\xdf" - "\x9a\x9d\xf1\x0d", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, -}; + .ent_reseed = "\xE0\x5B\x69\xC5\xF9\xD4\x5A\x1F\xC1\x71\x0C" + "\x37\x6F\xFE\x31\xE0\xEF\x3E\x9B\xD5\x46\x43" + "\xA2\x15\xFA\x86\x75\x1C\x95\x9F\xE6\xD6\x41" + "\x50\x36\x0F\x67\x68\x4A\x72\x32\x85\xB0\xCB" + "\xA4\x0D\x1F\xA2\x43\xCA\x30\xF1\x42\xF8\xC4" + "\x17\x6A\xD1\x2D\x43\x46\x8C\xA5\x72\x3C\xB1" + "\x44\x8E\xA1\x75\xAA\x20\x30\xDD\xCD\x0B\x5A" + "\x0D\xE6\x28\xCA\xBC\xA9\x3B\x11\x23\x88\x85" + "\xDF\xD8\x84\x11\x89\x7A\x4F\x00\x90\x0B\xD8" + "\x8A\x35\xE9\x5F\xEC\x05\x42\x15\xCA\x7E\xA3" + "\xEF\xEF\xE3\xB7\xBE\x96\x8C\x36\x7D\x15\x3C" + "\x7A\x78\x00\x61\xAF\x62\x45\xA7\x4B\xAE\x4A" + "\xFD\xC9\xE0\x89\x53\x36\x71\x8F\x38\xC4\x00" + "\x57\xD9\xE6\xC1\xEC\xBF\xF7\x4B\x3F\x55\xD6" + "\x54\x15\x72\xB2\x23\x76\xD1\x4E\x8E\x7E\xFB" + "\xC8\xD6\xA4\xA4\x7E\x8E\xD8\x76\xD3\xEB\x90" + "\x90\xEB\xB3\x84\x26\x34\x93\x36\xCA\xA9\x12" + "\xD3\x6D\x84\x07\xE1\x0E\xE7\x63\x24\x54\x90" + "\x42\x8C\x6B\xE7\x21\x53\x2D\x16\xE9\x68\xA9" + "\xC2\x9A\x7A\x93\x31\x5E\x35\x72\xE2\x0F\x3D" + "\x55\x41\x8C\xC5\xD1\xBB\xEE\x5F\x3C\x95\x52" + "\x2A\x65\x47\xB6\x84\x6A\x05\x19\xD9\xE7\x68" + "\x15\xFA\x49\xD9\x9D\xFD\x47\x9F\xB9\xA6\xBB" + "\xA8\xD4\x22\x6C\x8B\x59\x47\xEF\xD1\xD0\xBF" + "\xBC\xE4\x53\x31\x2F\xA5\xD4\x2C\x89\xCA\xE5" + "\x29\x64\xF8\x51\x2A\x02\xDE\x31\x0D\x54\x0E" + "\x0E\xB8\x78\xE6\x2A\x3E\x31\xA2\xA4\xCD\x91" + "\x79\xF2\x9B\x04\xA0\xDB\x78\xAC\x0D\xB5\xCA" + "\x60\x4C\x08\x96\xCA\x8A\xE9\x93\x9F\x62\x38" + "\xAE", + .ent_reseed_len = 320, + .addtl_reseed = "\xD5\x46\x71\x38\x46\xE0\xC1\x27\x2C\xF1\x07" + "\xDD\x29\x73\xD7\xF4\x5A\x3A\xE0\x99\x98\x0A" + "\xEB\xA5\x9E\x2E\x49\x21\x7B\x18\xC0\xD8\x3D" + "\xEE\x49\xF9\x52\x7C\x55\x5E\x5E\x06\xC2\x7E" + "\x34\x3A\xA5\xB7\x78\x21\xC1\xB8\x8B\x4E\x07" + "\x1F\x3F\xC4\xB4\x9B\x3F\x20\x2D\xEE\x70\x3B" + "\x18\xCF\x2B\x50\x15\x1B\xF3\x6C\xE7\x9F\x2A" + "\x2B\x69\x53\xCA\x88\x41\xA9\x07\x31\x14\x55" + "\xBD\x75\x49\x68\x98\x48\xCA\x46\xA5\xEC\xAA" + "\x9D\x8E\x6F\x40\xBA\xCA\xC8\xE9\x9F\xA4\xC5" + "\x94\x89\x2C\x4D\xE4\x0A\x66\xD3\xDB\x1A\xD9" + "\xA7\x3F\x6B\x0A\xE0\xE4\xDC\x0B\x8B\x64\xBF" + "\xB4\x95\xA1\xAE\x92\xA8\x7C\xE2\x4B\xED\xFD" + "\xFD\xE0\x54\x48\x7C\x25\xD6\xD1\x0A\xAB\x5E" + "\x33\x2F\x1D\xD3\x62\x47\xAB\x35\x8C\xA1\xC2" + "\x75\xDD\x75\xCA\x09\xE1\x38\xDE\x87\x79\x0C" + "\xD7\x5D\x3E\x6D\x28\x8F\x12\x98\x2C\x26\x34" + "\x91\x0B\x6B\xB7\x73", + .addtl_reseed_len = 192, -static const struct drbg_testvec drbg_nopr_ctr_aes256_tv_template[] = { - { - .entropy = (unsigned char *) - "\x36\x40\x19\x40\xfa\x8b\x1f\xba\x91\xa1\x66\x1f" - "\x21\x1d\x78\xa0\xb9\x38\x9a\x74\xe5\xbc\xcf\xec" - "\xe8\xd7\x66\xaf\x1a\x6d\x3b\x14\x49\x6f\x25\xb0" - "\xf1\x30\x1b\x4f\x50\x1b\xe3\x03\x80\xa1\x37\xeb", - .entropylen = 48, - .expected = (unsigned char *) - "\x58\x62\xeb\x38\xbd\x55\x8d\xd9\x78\xa6\x96\xe6" - "\xdf\x16\x47\x82\xdd\xd8\x87\xe7\xe9\xa6\xc9\xf3" - "\xf1\xfb\xaf\xb7\x89\x41\xb5\x35\xa6\x49\x12\xdf" - "\xd2\x24\xc6\xdc\x74\x54\xe5\x25\x0b\x3d\x97\x16" - "\x5e\x16\x26\x0c\x2f\xaf\x1c\xc7\x73\x5c\xb7\x5f" - "\xb4\xf0\x7e\x1d", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, -}; + .addtla = "\xC8\xE1\x03\x59\xEA\x9F\xD3\x1F\xCC\xCB\x5A\x3E" + "\x23\xDB\x47\x75\x1B\x3A\x6C\x0B\xED\xE6\xC0\xB6" + "\x4B\x82\x53\x5B\x6D\xEE\x2B\x97\x0F\x59\x07\xA4" + "\xFE\xE2\x26\x4F\xFF\xF7\x46\xAF\x62\xC4\x42\xE8" + "\x06\xFA\x1F\xAA\x66\xF3\xA4\xCF\x85\x02\x3C\x11" + "\xEF\xD2\x16\x13\x7A\xBD\x03\x66\xC3\x4D\x6F\x3A" + "\xE5\xD3\xFF\x92\xB6\x45\xB8\x88\x94\x42\x2E\x84" + "\x02\xA5\x54\x12\xBF\xCB\xF1\x6E\x1C\x0C\x23\xFE" + "\x8A\xFD\xF5\x1A\x4C\xD6\x2A\x34\x7F\x21\x50\xBB" + "\x06\x64\x9A\x77\x70\x59\x1D\x12\xD1\xA0\x10\x70" + "\xD7\x4F\x3C\xEE\x82\xEF\x5B\x35\x8F\x05\xF6\x51" + "\xBC\x28\xE1\xB1\x54\xFF\x25\x12\x16\x2C\x62\xFC" + "\xB9\x74\x5E\x78\x41\xB2\x04\x80\x4E\xB1\x43\x2E" + "\x88\x7F\x34\xA4\x33\x66\xE8\x68\x60\x54\xEB\xCE" + "\xD1\x5F\xC4\xD6\x21\x5E\x22\x1A\x7E\xC5\x6D\xB7" + "\x93\x8F\x9C\x77\x6E\x56\xA5\xA8\xF7\xB2\x10\x19", + .addtlb = "\xB8\x1E\x9E\xE2\xB3\xE4\x04\x43\x51\x7B\x96\x32" + "\xAC\x95\xF2\x1E\x5E\x7A\xBF\x68\xE3\x7A\xCE\xE5" + "\x2B\x3B\xB0\x34\x7F\xE1\xB5\x37\x3C\x5B\xD2\x6B" + "\x17\xF6\x18\xAF\x7C\x01\xA5\x84\xFE\x07\x0B\x46" + "\xCC\x96\x61\xAB\xCD\x81\x95\x8A\x8A\xB6\xD8\xCC" + "\x94\x80\x45\xF6\xFF\x95\x3A\xB8\xDC\xBF\xB4\xBF" + "\x26\x8C\xE9\x79\x05\x58\x9C\x03\x08\x45\xB5\xC4" + "\xD8\xB4\xCD\x76\x13\xAE\x2B\xCC\xB5\x3E\x3C\x65" + "\x7A\xAA\xDC\x9B\x0B\x13\x8B\x82\x5A\x39\x60\x9A" + "\xF7\xA8\x38\xB5\x83\x8E\x0B\xD1\xE6\xBF\xA1\xDC" + "\x30\x45\xCC\x67\x41\x0F\xF9\x86\x27\xE0\x22\x3E" + "\x0D\x1F\x92\x13\x16\x9B\x84\x79\x91\xFE\xBC\xDF" + "\x15\x6C\xDC\xAE\xC5\x64\x46\x9C\xE8\xEA\xBB\x9D" + "\x27\xA2\x1E\xDF\xB2\xF2\x98\xB4\x88\x4E\x22\x5F" + "\x3C\xD0\x35\x2C\x5C\x89\xC7\xEC\xE3\xF3\x09\x60" + "\xEF\xAC\x78\xBF\x94\xAA\x8C\x30\x7F\xCF\xE4\x4B", + .addtllen = 192, -static const struct drbg_testvec drbg_nopr_ctr_aes128_tv_template[] = { - { - .entropy = (unsigned char *) - "\x87\xe1\xc5\x32\x99\x7f\x57\xa3\x5c\x28\x6d\xe8" - "\x64\xbf\xf2\x64\xa3\x9e\x98\xdb\x6c\x10\x78\x7f", - .entropylen = 24, - .expected = (unsigned char *) - "\x2c\x14\x7e\x24\x11\x9a\xd8\xd4\xb2\xed\x61\xc1" - "\x53\xd0\x50\xc9\x24\xff\x59\x75\x15\xf1\x17\x3a" - "\x3d\xf4\x4b\x2c\x84\x28\xef\x89\x0e\xb9\xde\xf3" - "\xe4\x78\x04\xb2\xfd\x9b\x35\x7f\xe1\x3f\x8a\x3e" - "\x10\xc8\x67\x0a\xf9\xdf\x2d\x6c\x96\xfb\xb2\xb8" - "\xcb\x2d\xd6\xb0", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\x71\xbd\xce\x35\x42\x7d\x20\xbf\x58\xcf\x17\x74" - "\xce\x72\xd8\x33\x34\x50\x2d\x8f\x5b\x14\xc4\xdd", - .entropylen = 24, - .expected = (unsigned char *) - "\x97\x33\xe8\x20\x12\xe2\x7b\xa1\x46\x8f\xf2\x34" - "\xb3\xc9\xb6\x6b\x20\xb2\x4f\xee\x27\xd8\x0b\x21" - "\x8c\xff\x63\x73\x69\x29\xfb\xf3\x85\xcd\x88\x8e" - "\x43\x2c\x71\x8b\xa2\x55\xd2\x0f\x1d\x7f\xe3\xe1" - "\x2a\xa3\xe9\x2c\x25\x89\xc7\x14\x52\x99\x56\xcc" - "\xc3\xdf\xb3\x81", - .expectedlen = 64, - .addtla = (unsigned char *) - "\x66\xef\x42\xd6\x9a\x8c\x3d\x6d\x4a\x9e\x95\xa6" - "\x91\x4d\x81\x56", - .addtlb = (unsigned char *) - "\xe3\x18\x83\xd9\x4b\x5e\xc4\xcc\xaa\x61\x2f\xbb" - "\x4a\x55\xd1\xc6", - .addtllen = 16, - .pers = NULL, - .perslen = 0, - }, { - .entropy = (unsigned char *) - "\xca\x4b\x1e\xfa\x75\xbd\x69\x36\x38\x73\xb8\xf9" - "\xdb\x4d\x35\x0e\x47\xbf\x6c\x37\x72\xfd\xf7\xa9", - .entropylen = 24, - .expected = (unsigned char *) - "\x59\xc3\x19\x79\x1b\xb1\xf3\x0e\xe9\x34\xae\x6e" - "\x8b\x1f\xad\x1f\x74\xca\x25\x45\x68\xb8\x7f\x75" - "\x12\xf8\xf2\xab\x4c\x23\x01\x03\x05\xe1\x70\xee" - "\x75\xd8\xcb\xeb\x23\x4c\x7a\x23\x6e\x12\x27\xdb" - "\x6f\x7a\xac\x3c\x44\xb7\x87\x4b\x65\x56\x74\x45" - "\x34\x30\x0c\x3d", - .expectedlen = 64, - .addtla = NULL, - .addtlb = NULL, - .addtllen = 0, - .pers = (unsigned char *) - "\xeb\xaa\x60\x2c\x4d\xbe\x33\xff\x1b\xef\xbf\x0a" - "\x0b\xc6\x97\x54", - .perslen = 16, - }, { - .entropy = (unsigned char *) - "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98" - "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6", - .entropylen = 24, - .expected = (unsigned char *) - "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a" - "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95" - "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f" - "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a" - "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a" - "\x2b\x49\x1e\x5c", - .expectedlen = 64, - .addtla = (unsigned char *) - "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2" - "\x44\x85\xe7\xfe", - .addtlb = (unsigned char *) - "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4" - "\x82\x16\x62\x7f", - .addtllen = 16, - .pers = (unsigned char *) - "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f" - "\x8e\xcf\xe0\x02", - .perslen = 16, - }, + .expected = "\x93\xFF\x4F\x4A\xA7\xE0\xFC\x3B\xCF\xCE\x57\xCD" + "\xFD\xE9\x94\x6D\x0D\x45\x7E\xA3\x98\xBB\xE6\x54" + "\x36\xF9\x92\xE6\xBB\xC5\x93\x16\x69\x35\x01\xF0" + "\x5A\xE2\x43\xFC\x73\x7C\xA3\x5C\x5B\x49\x72\x69" + "\x6A\xC4\xB6\xD4\xB2\x48\x27\x72\xCA\xE3\xF3\xB8" + "\xD6\x95\x9F\x39\xC8\xD7\x72\xAF\xC2\x7C\x75\xE5" + "\xA4\xF7\x52\x4F\xDF\x80\x75\xCA\x4B\xFA\x75\x9A" + "\x7A\x8D\x48\x94\x30\x1C\x82\x5E\xD6\x3F\xF1\x78" + "\x84\xAA\x8D\x8B\x4F\x6A\x20\x12\xA2\x65\xC5\x02" + "\x32\xA1\xE4\x6B\x86\x2F\xCF\x92\xCD\x01\x55\xF7" + "\xB8\xAB\xC3\x2C\x42\xC3\xFD\x9B\x59\x2D\x47\x8E" + "\xB6\x8D\xE7\x04\x2E\x67\xD9\x07\x14\xA3\xF2\x74" + "\x79\x9C\xAB\xC6\xD6\x52\x3E\x91\x81\xA4\x3C\x9A" + "\x3E\x10\x1E\xD0\x28\xBC\x1C\x50\xF0\xB6\xEC\x01" + "\xE5\x40\x16\x08\xB5\x58\xE0\xC4\xC2\x9A\xBB\x13" + "\xAB\x10\x4B\x07\x24\x09\xEB\xF9\x5E\xAA\x3E\x3A" + "\x25\x34\x5B\x97\x92\xF9\x46\x8A\x8E\x5A\x06\x9C" + "\x2B\x1C\x8E\x47\x19\xC3\x3B\x14\x8A\xC1\xEB\xF7" + "\xB0\xA2\x05\xE0\x70\x12\x88\x21\xFF\xC0\x35\x6D" + "\xE9\x08\x7E\x11\x6E\xD7\x16\x48\x24\x43\xAF\x33" + "\xA3\x48\x44\x91\xC5\x32\x1D\x87\xF6\x9B\x10\x1C" + "\xA4\x7A\x74\x23\xB3\xFC\xB9\x87\x08\xE6\x9A\xEF" + "\xD5\x93\x82\x17\xD4\x78\xDA\x46\x34\xC2\x61\x8C" + "\xB7\x53\x89\xC4\x8A\xD8\xA0\x2E\xCE\xCA\x24\x16" + "\xF0\x18\x7F\xC3\x12\x3F\xD0\xB1\xEF\x37\x99\xA8" + "\x04\x1F\x76\x50\x81\x08\xCD\x4D\x43\xEF\x64\xB6" + "\x03\x57\xB7\x5F\xDD\xF6\xBA\x34\xE2\x88\xE7\x1F" + "\x62\xA5\xA4\x05\xEB\x1A\xFE\x0B\xFE\x74\x7D\x64" + "\x29\x83\xE8\x0B\x97\x7D\x94\x5B\xF9\x3C\x8E\xC8" + "\x6B\xCD\xAD\x63\x32\x6E\x00\xBF\x8E\x57\xF2\x32" + "\x88\x53\x17\x40\xE3\xF8\xF8\xD9\xFD\xCD\x76\x84" + "\xC6\xFD\xB1\x10\x40\xED\x75\xDD\xBD\x78\x8B\x0A" + "\x61\x1E\xCC\xC4\x4F\x95\xF1\x2F\x8F\x5A\xF0\x12" + "\x00\xCE\x75\xB8\xE9\xAB\x63\xC0\x7A\xF6\x9A\x47" + "\xD2\x3C\xB0\xAD\xAF\x03\xDF\x25\xDD\x0C\x0F\xB6" + "\x29\x09\x0F\x28\x5E\xA8\x67\xBB\xC9\x78\xBE\x12" + "\xD8\xD6\xD0\x98\x82\x29\xA3\x82\xFB\x8E\x1C\x79" + "\x28\x52\x22\x73\x3C\x6F\xB5\x33\xFF\x40\x26\x4C" + "\x30\xE4\xE0\x39\x59\x72\x65\x79\x9F\xB7\x89\x87" + "\x64\xAC\x45\x11\x0D\xDD\xC0\x44\x5E\x0D\xDF\xDB" + "\x91\x42\x5F\x52\x7F\xBB\x66\xEE\x32\x90\x8F\x6F" + "\xF8\xB9\xFE\xEA\x42\xFB\x60\x2B\xE3\xD9\xB2\xD1" + "\x74\x37\x14\xC6\xDA\x68\xE6\x09", + .expectedlen = 512, + } }; /* Cast5 test vectors from RFC 2144 */ |
