Skip to content

Commit 5102981

Browse files
smuellerDDherbertx
authored andcommitted
crypto: drbg - prevent invalid SG mappings
When using SGs, only heap memory (memory that is valid as per virt_addr_valid) is allowed to be referenced. The CTR DRBG used to reference the caller-provided memory directly in an SG. In case the caller provided stack memory pointers, the SG mapping is not considered to be valid. In some cases, this would even cause a paging fault. The change adds a new scratch buffer that is used unconditionally to catch the cases where the caller-provided buffer is not suitable for use in an SG. The crypto operation of the CTR DRBG produces its output with that scratch buffer and finally copies the content of the scratch buffer to the caller's buffer. The scratch buffer is allocated during allocation time of the CTR DRBG as its access is protected with the DRBG mutex. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent c8467f7 commit 5102981

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

crypto/drbg.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
262262
u8 *inbuf, u32 inbuflen,
263263
u8 *outbuf, u32 outlen);
264264
#define DRBG_CTR_NULL_LEN 128
265+
#define DRBG_OUTSCRATCHLEN DRBG_CTR_NULL_LEN
265266

266267
/* BCC function for CTR DRBG as defined in 10.4.3 */
267268
static int drbg_ctr_bcc(struct drbg_state *drbg,
@@ -1644,6 +1645,9 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)
16441645
kfree(drbg->ctr_null_value_buf);
16451646
drbg->ctr_null_value = NULL;
16461647

1648+
kfree(drbg->outscratchpadbuf);
1649+
drbg->outscratchpadbuf = NULL;
1650+
16471651
return 0;
16481652
}
16491653

@@ -1708,6 +1712,15 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
17081712
drbg->ctr_null_value = (u8 *)PTR_ALIGN(drbg->ctr_null_value_buf,
17091713
alignmask + 1);
17101714

1715+
drbg->outscratchpadbuf = kmalloc(DRBG_OUTSCRATCHLEN + alignmask,
1716+
GFP_KERNEL);
1717+
if (!drbg->outscratchpadbuf) {
1718+
drbg_fini_sym_kernel(drbg);
1719+
return -ENOMEM;
1720+
}
1721+
drbg->outscratchpad = (u8 *)PTR_ALIGN(drbg->outscratchpadbuf,
1722+
alignmask + 1);
1723+
17111724
return alignmask;
17121725
}
17131726

@@ -1737,15 +1750,16 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
17371750
u8 *outbuf, u32 outlen)
17381751
{
17391752
struct scatterlist sg_in;
1753+
int ret;
17401754

17411755
sg_init_one(&sg_in, inbuf, inlen);
17421756

17431757
while (outlen) {
1744-
u32 cryptlen = min_t(u32, inlen, outlen);
1758+
u32 cryptlen = min3(inlen, outlen, (u32)DRBG_OUTSCRATCHLEN);
17451759
struct scatterlist sg_out;
1746-
int ret;
17471760

1748-
sg_init_one(&sg_out, outbuf, cryptlen);
1761+
/* Output buffer may not be valid for SGL, use scratchpad */
1762+
sg_init_one(&sg_out, drbg->outscratchpad, cryptlen);
17491763
skcipher_request_set_crypt(drbg->ctr_req, &sg_in, &sg_out,
17501764
cryptlen, drbg->V);
17511765
ret = crypto_skcipher_encrypt(drbg->ctr_req);
@@ -1761,14 +1775,19 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
17611775
break;
17621776
}
17631777
default:
1764-
return ret;
1778+
goto out;
17651779
}
17661780
init_completion(&drbg->ctr_completion);
17671781

1782+
memcpy(outbuf, drbg->outscratchpad, cryptlen);
1783+
17681784
outlen -= cryptlen;
17691785
}
1786+
ret = 0;
17701787

1771-
return 0;
1788+
out:
1789+
memzero_explicit(drbg->outscratchpad, DRBG_OUTSCRATCHLEN);
1790+
return ret;
17721791
}
17731792
#endif /* CONFIG_CRYPTO_DRBG_CTR */
17741793

include/crypto/drbg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct drbg_state {
124124
struct skcipher_request *ctr_req; /* CTR mode request handle */
125125
__u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */
126126
__u8 *ctr_null_value; /* CTR mode aligned zero buf */
127+
__u8 *outscratchpadbuf; /* CTR mode output scratchpad */
128+
__u8 *outscratchpad; /* CTR mode aligned outbuf */
127129
struct completion ctr_completion; /* CTR mode async handler */
128130
int ctr_async_err; /* CTR mode async error */
129131

0 commit comments

Comments
 (0)