mirror of https://github.com/torvalds/linux.git
crypto: drbg - Replace AES cipher calls with library calls
Replace aes used in drbg with library calls. Signed-off-by: Harsh Jain <h.jain@amd.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
6c4fed5fee
commit
ba0570bdf1
|
|
@ -10,33 +10,34 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
#include <crypto/aes.h>
|
||||||
#include <crypto/df_sp80090a.h>
|
#include <crypto/df_sp80090a.h>
|
||||||
#include <crypto/internal/drbg.h>
|
#include <crypto/internal/drbg.h>
|
||||||
|
|
||||||
static void drbg_kcapi_symsetkey(struct crypto_cipher *tfm,
|
static void drbg_kcapi_symsetkey(struct crypto_aes_ctx *aesctx,
|
||||||
const unsigned char *key,
|
const unsigned char *key,
|
||||||
u8 keylen);
|
u8 keylen);
|
||||||
static int drbg_kcapi_sym(struct crypto_cipher *tfm, unsigned char *outval,
|
static int drbg_kcapi_sym(struct crypto_aes_ctx *aesctx, unsigned char *outval,
|
||||||
const struct drbg_string *in, u8 blocklen_bytes);
|
const struct drbg_string *in, u8 blocklen_bytes);
|
||||||
|
|
||||||
static void drbg_kcapi_symsetkey(struct crypto_cipher *tfm,
|
static void drbg_kcapi_symsetkey(struct crypto_aes_ctx *aesctx,
|
||||||
const unsigned char *key, u8 keylen)
|
const unsigned char *key, u8 keylen)
|
||||||
{
|
{
|
||||||
crypto_cipher_setkey(tfm, key, keylen);
|
aes_expandkey(aesctx, key, keylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drbg_kcapi_sym(struct crypto_cipher *tfm, unsigned char *outval,
|
static int drbg_kcapi_sym(struct crypto_aes_ctx *aesctx, unsigned char *outval,
|
||||||
const struct drbg_string *in, u8 blocklen_bytes)
|
const struct drbg_string *in, u8 blocklen_bytes)
|
||||||
{
|
{
|
||||||
/* there is only component in *in */
|
/* there is only component in *in */
|
||||||
BUG_ON(in->len < blocklen_bytes);
|
BUG_ON(in->len < blocklen_bytes);
|
||||||
crypto_cipher_encrypt_one(tfm, outval, in->buf);
|
aes_encrypt(aesctx, outval, in->buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BCC function for CTR DRBG as defined in 10.4.3 */
|
/* BCC function for CTR DRBG as defined in 10.4.3 */
|
||||||
|
|
||||||
static int drbg_ctr_bcc(struct crypto_cipher *tfm,
|
static int drbg_ctr_bcc(struct crypto_aes_ctx *aesctx,
|
||||||
unsigned char *out, const unsigned char *key,
|
unsigned char *out, const unsigned char *key,
|
||||||
struct list_head *in,
|
struct list_head *in,
|
||||||
u8 blocklen_bytes,
|
u8 blocklen_bytes,
|
||||||
|
|
@ -50,7 +51,7 @@ static int drbg_ctr_bcc(struct crypto_cipher *tfm,
|
||||||
drbg_string_fill(&data, out, blocklen_bytes);
|
drbg_string_fill(&data, out, blocklen_bytes);
|
||||||
|
|
||||||
/* 10.4.3 step 2 / 4 */
|
/* 10.4.3 step 2 / 4 */
|
||||||
drbg_kcapi_symsetkey(tfm, key, keylen);
|
drbg_kcapi_symsetkey(aesctx, key, keylen);
|
||||||
list_for_each_entry(curr, in, list) {
|
list_for_each_entry(curr, in, list) {
|
||||||
const unsigned char *pos = curr->buf;
|
const unsigned char *pos = curr->buf;
|
||||||
size_t len = curr->len;
|
size_t len = curr->len;
|
||||||
|
|
@ -59,7 +60,7 @@ static int drbg_ctr_bcc(struct crypto_cipher *tfm,
|
||||||
/* 10.4.3 step 4.2 */
|
/* 10.4.3 step 4.2 */
|
||||||
if (blocklen_bytes == cnt) {
|
if (blocklen_bytes == cnt) {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
ret = drbg_kcapi_sym(tfm, out, &data, blocklen_bytes);
|
ret = drbg_kcapi_sym(aesctx, out, &data, blocklen_bytes);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +72,7 @@ static int drbg_ctr_bcc(struct crypto_cipher *tfm,
|
||||||
}
|
}
|
||||||
/* 10.4.3 step 4.2 for last block */
|
/* 10.4.3 step 4.2 for last block */
|
||||||
if (cnt)
|
if (cnt)
|
||||||
ret = drbg_kcapi_sym(tfm, out, &data, blocklen_bytes);
|
ret = drbg_kcapi_sym(aesctx, out, &data, blocklen_bytes);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +118,7 @@ static int drbg_ctr_bcc(struct crypto_cipher *tfm,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Derivation Function for CTR DRBG as defined in 10.4.2 */
|
/* Derivation Function for CTR DRBG as defined in 10.4.2 */
|
||||||
int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
|
int crypto_drbg_ctr_df(struct crypto_aes_ctx *aesctx,
|
||||||
unsigned char *df_data, size_t bytes_to_return,
|
unsigned char *df_data, size_t bytes_to_return,
|
||||||
struct list_head *seedlist,
|
struct list_head *seedlist,
|
||||||
u8 blocklen_bytes,
|
u8 blocklen_bytes,
|
||||||
|
|
@ -195,7 +196,7 @@ int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
|
||||||
*/
|
*/
|
||||||
drbg_cpu_to_be32(i, iv);
|
drbg_cpu_to_be32(i, iv);
|
||||||
/* 10.4.2 step 9.2 -- BCC and concatenation with temp */
|
/* 10.4.2 step 9.2 -- BCC and concatenation with temp */
|
||||||
ret = drbg_ctr_bcc(tfm, temp + templen, K, &bcc_list,
|
ret = drbg_ctr_bcc(aesctx, temp + templen, K, &bcc_list,
|
||||||
blocklen_bytes, keylen);
|
blocklen_bytes, keylen);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -211,7 +212,7 @@ int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
|
||||||
/* 10.4.2 step 12: overwriting of outval is implemented in next step */
|
/* 10.4.2 step 12: overwriting of outval is implemented in next step */
|
||||||
|
|
||||||
/* 10.4.2 step 13 */
|
/* 10.4.2 step 13 */
|
||||||
drbg_kcapi_symsetkey(tfm, temp, keylen);
|
drbg_kcapi_symsetkey(aesctx, temp, keylen);
|
||||||
while (generated_len < bytes_to_return) {
|
while (generated_len < bytes_to_return) {
|
||||||
short blocklen = 0;
|
short blocklen = 0;
|
||||||
/*
|
/*
|
||||||
|
|
@ -219,7 +220,7 @@ int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
|
||||||
* implicit as the key is only drbg_blocklen in size based on
|
* implicit as the key is only drbg_blocklen in size based on
|
||||||
* the implementation of the cipher function callback
|
* the implementation of the cipher function callback
|
||||||
*/
|
*/
|
||||||
ret = drbg_kcapi_sym(tfm, X, &cipherin, blocklen_bytes);
|
ret = drbg_kcapi_sym(aesctx, X, &cipherin, blocklen_bytes);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
blocklen = (blocklen_bytes <
|
blocklen = (blocklen_bytes <
|
||||||
|
|
|
||||||
|
|
@ -1506,10 +1506,9 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
|
||||||
#ifdef CONFIG_CRYPTO_DRBG_CTR
|
#ifdef CONFIG_CRYPTO_DRBG_CTR
|
||||||
static int drbg_fini_sym_kernel(struct drbg_state *drbg)
|
static int drbg_fini_sym_kernel(struct drbg_state *drbg)
|
||||||
{
|
{
|
||||||
struct crypto_cipher *tfm =
|
struct crypto_aes_ctx *aesctx = (struct crypto_aes_ctx *)drbg->priv_data;
|
||||||
(struct crypto_cipher *)drbg->priv_data;
|
|
||||||
if (tfm)
|
kfree(aesctx);
|
||||||
crypto_free_cipher(tfm);
|
|
||||||
drbg->priv_data = NULL;
|
drbg->priv_data = NULL;
|
||||||
|
|
||||||
if (drbg->ctr_handle)
|
if (drbg->ctr_handle)
|
||||||
|
|
@ -1528,20 +1527,16 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
|
||||||
|
|
||||||
static int drbg_init_sym_kernel(struct drbg_state *drbg)
|
static int drbg_init_sym_kernel(struct drbg_state *drbg)
|
||||||
{
|
{
|
||||||
struct crypto_cipher *tfm;
|
struct crypto_aes_ctx *aesctx;
|
||||||
struct crypto_skcipher *sk_tfm;
|
struct crypto_skcipher *sk_tfm;
|
||||||
struct skcipher_request *req;
|
struct skcipher_request *req;
|
||||||
unsigned int alignmask;
|
unsigned int alignmask;
|
||||||
char ctr_name[CRYPTO_MAX_ALG_NAME];
|
char ctr_name[CRYPTO_MAX_ALG_NAME];
|
||||||
|
|
||||||
tfm = crypto_alloc_cipher(drbg->core->backend_cra_name, 0, 0);
|
aesctx = kzalloc(sizeof(*aesctx), GFP_KERNEL);
|
||||||
if (IS_ERR(tfm)) {
|
if (!aesctx)
|
||||||
pr_info("DRBG: could not allocate cipher TFM handle: %s\n",
|
return -ENOMEM;
|
||||||
drbg->core->backend_cra_name);
|
drbg->priv_data = aesctx;
|
||||||
return PTR_ERR(tfm);
|
|
||||||
}
|
|
||||||
BUG_ON(drbg_blocklen(drbg) != crypto_cipher_blocksize(tfm));
|
|
||||||
drbg->priv_data = tfm;
|
|
||||||
|
|
||||||
if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
|
if (snprintf(ctr_name, CRYPTO_MAX_ALG_NAME, "ctr(%s)",
|
||||||
drbg->core->backend_cra_name) >= CRYPTO_MAX_ALG_NAME) {
|
drbg->core->backend_cra_name) >= CRYPTO_MAX_ALG_NAME) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define _CRYPTO_DF80090A_H
|
#define _CRYPTO_DF80090A_H
|
||||||
|
|
||||||
#include <crypto/internal/cipher.h>
|
#include <crypto/internal/cipher.h>
|
||||||
|
#include <crypto/aes.h>
|
||||||
|
|
||||||
static inline int crypto_drbg_ctr_df_datalen(u8 statelen, u8 blocklen)
|
static inline int crypto_drbg_ctr_df_datalen(u8 statelen, u8 blocklen)
|
||||||
{
|
{
|
||||||
|
|
@ -17,7 +18,7 @@ static inline int crypto_drbg_ctr_df_datalen(u8 statelen, u8 blocklen)
|
||||||
statelen + blocklen; /* temp */
|
statelen + blocklen; /* temp */
|
||||||
}
|
}
|
||||||
|
|
||||||
int crypto_drbg_ctr_df(struct crypto_cipher *tfm,
|
int crypto_drbg_ctr_df(struct crypto_aes_ctx *aes,
|
||||||
unsigned char *df_data,
|
unsigned char *df_data,
|
||||||
size_t bytes_to_return,
|
size_t bytes_to_return,
|
||||||
struct list_head *seedlist,
|
struct list_head *seedlist,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue