s390/crypto: simplify return code handling
The CPACF instructions can complete with three different condition codes: CC=0 for successful completion, CC=1 if the protected key verification failed, and CC=3 for partial completion. The inline functions will restart the CPACF instruction for partial completion, this removes the CC=3 case. The CC=1 case is only relevant for the protected key functions of the KM, KMC, KMAC and KMCTR instructions. As the protected key functions are not used by the current code, there is no need for any kind of return code handling. Reviewed-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
edc63a3785
commit
0177db01ad
|
@ -324,9 +324,7 @@ static int ecb_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
|
||||||
u8 *out = walk->dst.virt.addr;
|
u8 *out = walk->dst.virt.addr;
|
||||||
u8 *in = walk->src.virt.addr;
|
u8 *in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = cpacf_km(func, param, out, in, n);
|
cpacf_km(func, param, out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||||
|
@ -460,9 +458,7 @@ static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
u8 *out = walk->dst.virt.addr;
|
u8 *out = walk->dst.virt.addr;
|
||||||
u8 *in = walk->src.virt.addr;
|
u8 *in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = cpacf_kmc(func, ¶m, out, in, n);
|
cpacf_kmc(func, ¶m, out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||||
|
@ -640,9 +636,7 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
|
memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak));
|
||||||
memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
|
memcpy(pcc_param.key, xts_ctx->pcc_key, 32);
|
||||||
/* remove decipher modifier bit from 'func' and call PCC */
|
/* remove decipher modifier bit from 'func' and call PCC */
|
||||||
ret = cpacf_pcc(func & 0x7f, &pcc_param.key[offset]);
|
cpacf_pcc(func & 0x7f, &pcc_param.key[offset]);
|
||||||
if (ret < 0)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
memcpy(xts_param.key, xts_ctx->key, 32);
|
memcpy(xts_param.key, xts_ctx->key, 32);
|
||||||
memcpy(xts_param.init, pcc_param.xts, 16);
|
memcpy(xts_param.init, pcc_param.xts, 16);
|
||||||
|
@ -652,9 +646,7 @@ static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
out = walk->dst.virt.addr;
|
out = walk->dst.virt.addr;
|
||||||
in = walk->src.virt.addr;
|
in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = cpacf_km(func, &xts_param.key[offset], out, in, n);
|
cpacf_km(func, &xts_param.key[offset], out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||||
|
@ -798,12 +790,7 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
n = __ctrblk_init(ctrptr, nbytes);
|
n = __ctrblk_init(ctrptr, nbytes);
|
||||||
else
|
else
|
||||||
n = AES_BLOCK_SIZE;
|
n = AES_BLOCK_SIZE;
|
||||||
ret = cpacf_kmctr(func, sctx->key, out, in, n, ctrptr);
|
cpacf_kmctr(func, sctx->key, out, in, n, ctrptr);
|
||||||
if (ret < 0 || ret != n) {
|
|
||||||
if (ctrptr == ctrblk)
|
|
||||||
spin_unlock(&ctrblk_lock);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
if (n > AES_BLOCK_SIZE)
|
if (n > AES_BLOCK_SIZE)
|
||||||
memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE,
|
memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE,
|
||||||
AES_BLOCK_SIZE);
|
AES_BLOCK_SIZE);
|
||||||
|
@ -830,10 +817,7 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
|
||||||
if (nbytes) {
|
if (nbytes) {
|
||||||
out = walk->dst.virt.addr;
|
out = walk->dst.virt.addr;
|
||||||
in = walk->src.virt.addr;
|
in = walk->src.virt.addr;
|
||||||
ret = cpacf_kmctr(func, sctx->key, buf, in,
|
cpacf_kmctr(func, sctx->key, buf, in, AES_BLOCK_SIZE, ctrbuf);
|
||||||
AES_BLOCK_SIZE, ctrbuf);
|
|
||||||
if (ret < 0 || ret != AES_BLOCK_SIZE)
|
|
||||||
return -EIO;
|
|
||||||
memcpy(out, buf, nbytes);
|
memcpy(out, buf, nbytes);
|
||||||
crypto_inc(ctrbuf, AES_BLOCK_SIZE);
|
crypto_inc(ctrbuf, AES_BLOCK_SIZE);
|
||||||
ret = blkcipher_walk_done(desc, walk, 0);
|
ret = blkcipher_walk_done(desc, walk, 0);
|
||||||
|
|
|
@ -95,9 +95,7 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||||
u8 *out = walk->dst.virt.addr;
|
u8 *out = walk->dst.virt.addr;
|
||||||
u8 *in = walk->src.virt.addr;
|
u8 *in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = cpacf_km(func, key, out, in, n);
|
cpacf_km(func, key, out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
nbytes &= DES_BLOCK_SIZE - 1;
|
nbytes &= DES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||||
|
@ -128,9 +126,7 @@ static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||||
u8 *out = walk->dst.virt.addr;
|
u8 *out = walk->dst.virt.addr;
|
||||||
u8 *in = walk->src.virt.addr;
|
u8 *in = walk->src.virt.addr;
|
||||||
|
|
||||||
ret = cpacf_kmc(func, ¶m, out, in, n);
|
cpacf_kmc(func, ¶m, out, in, n);
|
||||||
if (ret < 0 || ret != n)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
nbytes &= DES_BLOCK_SIZE - 1;
|
nbytes &= DES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, walk, nbytes);
|
ret = blkcipher_walk_done(desc, walk, nbytes);
|
||||||
|
@ -411,12 +407,7 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||||
n = __ctrblk_init(ctrptr, nbytes);
|
n = __ctrblk_init(ctrptr, nbytes);
|
||||||
else
|
else
|
||||||
n = DES_BLOCK_SIZE;
|
n = DES_BLOCK_SIZE;
|
||||||
ret = cpacf_kmctr(func, ctx->key, out, in, n, ctrptr);
|
cpacf_kmctr(func, ctx->key, out, in, n, ctrptr);
|
||||||
if (ret < 0 || ret != n) {
|
|
||||||
if (ctrptr == ctrblk)
|
|
||||||
spin_unlock(&ctrblk_lock);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
if (n > DES_BLOCK_SIZE)
|
if (n > DES_BLOCK_SIZE)
|
||||||
memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE,
|
memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE,
|
||||||
DES_BLOCK_SIZE);
|
DES_BLOCK_SIZE);
|
||||||
|
@ -441,10 +432,7 @@ static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
|
||||||
if (nbytes) {
|
if (nbytes) {
|
||||||
out = walk->dst.virt.addr;
|
out = walk->dst.virt.addr;
|
||||||
in = walk->src.virt.addr;
|
in = walk->src.virt.addr;
|
||||||
ret = cpacf_kmctr(func, ctx->key, buf, in,
|
cpacf_kmctr(func, ctx->key, buf, in, DES_BLOCK_SIZE, ctrbuf);
|
||||||
DES_BLOCK_SIZE, ctrbuf);
|
|
||||||
if (ret < 0 || ret != DES_BLOCK_SIZE)
|
|
||||||
return -EIO;
|
|
||||||
memcpy(out, buf, nbytes);
|
memcpy(out, buf, nbytes);
|
||||||
crypto_inc(ctrbuf, DES_BLOCK_SIZE);
|
crypto_inc(ctrbuf, DES_BLOCK_SIZE);
|
||||||
ret = blkcipher_walk_done(desc, walk, 0);
|
ret = blkcipher_walk_done(desc, walk, 0);
|
||||||
|
|
|
@ -58,7 +58,6 @@ static int ghash_update(struct shash_desc *desc,
|
||||||
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
|
struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
u8 *buf = dctx->buffer;
|
u8 *buf = dctx->buffer;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (dctx->bytes) {
|
if (dctx->bytes) {
|
||||||
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
||||||
|
@ -71,18 +70,14 @@ static int ghash_update(struct shash_desc *desc,
|
||||||
src += n;
|
src += n;
|
||||||
|
|
||||||
if (!dctx->bytes) {
|
if (!dctx->bytes) {
|
||||||
ret = cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf,
|
cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf,
|
||||||
GHASH_BLOCK_SIZE);
|
GHASH_BLOCK_SIZE);
|
||||||
if (ret != GHASH_BLOCK_SIZE)
|
|
||||||
return -EIO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = srclen & ~(GHASH_BLOCK_SIZE - 1);
|
n = srclen & ~(GHASH_BLOCK_SIZE - 1);
|
||||||
if (n) {
|
if (n) {
|
||||||
ret = cpacf_kimd(CPACF_KIMD_GHASH, dctx, src, n);
|
cpacf_kimd(CPACF_KIMD_GHASH, dctx, src, n);
|
||||||
if (ret != n)
|
|
||||||
return -EIO;
|
|
||||||
src += n;
|
src += n;
|
||||||
srclen -= n;
|
srclen -= n;
|
||||||
}
|
}
|
||||||
|
@ -98,17 +93,12 @@ static int ghash_update(struct shash_desc *desc,
|
||||||
static int ghash_flush(struct ghash_desc_ctx *dctx)
|
static int ghash_flush(struct ghash_desc_ctx *dctx)
|
||||||
{
|
{
|
||||||
u8 *buf = dctx->buffer;
|
u8 *buf = dctx->buffer;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (dctx->bytes) {
|
if (dctx->bytes) {
|
||||||
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
|
||||||
|
|
||||||
memset(pos, 0, dctx->bytes);
|
memset(pos, 0, dctx->bytes);
|
||||||
|
cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
|
||||||
ret = cpacf_kimd(CPACF_KIMD_GHASH, dctx, buf, GHASH_BLOCK_SIZE);
|
|
||||||
if (ret != GHASH_BLOCK_SIZE)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
dctx->bytes = 0;
|
dctx->bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,12 +135,7 @@ static int generate_entropy(u8 *ebuf, size_t nbytes)
|
||||||
else
|
else
|
||||||
h = ebuf;
|
h = ebuf;
|
||||||
/* generate sha256 from this page */
|
/* generate sha256 from this page */
|
||||||
if (cpacf_kimd(CPACF_KIMD_SHA_256, h,
|
cpacf_kimd(CPACF_KIMD_SHA_256, h, pg, PAGE_SIZE);
|
||||||
pg, PAGE_SIZE) != PAGE_SIZE) {
|
|
||||||
prng_errorflag = PRNG_GEN_ENTROPY_FAILED;
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (n < sizeof(hash))
|
if (n < sizeof(hash))
|
||||||
memcpy(ebuf, hash, n);
|
memcpy(ebuf, hash, n);
|
||||||
ret += n;
|
ret += n;
|
||||||
|
@ -148,7 +143,6 @@ static int generate_entropy(u8 *ebuf, size_t nbytes)
|
||||||
nbytes -= n;
|
nbytes -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
free_page((unsigned long)pg);
|
free_page((unsigned long)pg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -160,13 +154,11 @@ static void prng_tdes_add_entropy(void)
|
||||||
{
|
{
|
||||||
__u64 entropy[4];
|
__u64 entropy[4];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
ret = cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
|
cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
|
||||||
(char *)entropy, (char *)entropy,
|
(char *) entropy, (char *) entropy,
|
||||||
sizeof(entropy));
|
sizeof(entropy));
|
||||||
BUG_ON(ret < 0 || ret != sizeof(entropy));
|
|
||||||
memcpy(prng_data->prngws.parm_block, entropy, sizeof(entropy));
|
memcpy(prng_data->prngws.parm_block, entropy, sizeof(entropy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,21 +295,14 @@ static int __init prng_sha512_selftest(void)
|
||||||
0x21, 0xe4, 0xb0, 0x86, 0x44, 0xf6, 0x72, 0x7c,
|
0x21, 0xe4, 0xb0, 0x86, 0x44, 0xf6, 0x72, 0x7c,
|
||||||
0x36, 0x8c, 0x5a, 0x9f, 0x7a, 0x4b, 0x3e, 0xe2 };
|
0x36, 0x8c, 0x5a, 0x9f, 0x7a, 0x4b, 0x3e, 0xe2 };
|
||||||
|
|
||||||
int ret = 0;
|
|
||||||
u8 buf[sizeof(random)];
|
u8 buf[sizeof(random)];
|
||||||
struct ppno_ws_s ws;
|
struct ppno_ws_s ws;
|
||||||
|
|
||||||
memset(&ws, 0, sizeof(ws));
|
memset(&ws, 0, sizeof(ws));
|
||||||
|
|
||||||
/* initial seed */
|
/* initial seed */
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED, &ws, NULL, 0,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
|
||||||
seed, sizeof(seed));
|
&ws, NULL, 0, seed, sizeof(seed));
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("The prng self test seed operation for the "
|
|
||||||
"SHA-512 mode failed with rc=%d\n", ret);
|
|
||||||
prng_errorflag = PRNG_SELFTEST_FAILED;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check working states V and C */
|
/* check working states V and C */
|
||||||
if (memcmp(ws.V, V0, sizeof(V0)) != 0
|
if (memcmp(ws.V, V0, sizeof(V0)) != 0
|
||||||
|
@ -329,22 +314,10 @@ static int __init prng_sha512_selftest(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate random bytes */
|
/* generate random bytes */
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
||||||
&ws, buf, sizeof(buf), NULL, 0);
|
&ws, buf, sizeof(buf), NULL, 0);
|
||||||
if (ret < 0) {
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
||||||
pr_err("The prng self test generate operation for "
|
&ws, buf, sizeof(buf), NULL, 0);
|
||||||
"the SHA-512 mode failed with rc=%d\n", ret);
|
|
||||||
prng_errorflag = PRNG_SELFTEST_FAILED;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
|
||||||
&ws, buf, sizeof(buf), NULL, 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_err("The prng self test generate operation for "
|
|
||||||
"the SHA-512 mode failed with rc=%d\n", ret);
|
|
||||||
prng_errorflag = PRNG_SELFTEST_FAILED;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check against expected data */
|
/* check against expected data */
|
||||||
if (memcmp(buf, random, sizeof(random)) != 0) {
|
if (memcmp(buf, random, sizeof(random)) != 0) {
|
||||||
|
@ -392,26 +365,16 @@ static int __init prng_sha512_instantiate(void)
|
||||||
get_tod_clock_ext(seed + 48);
|
get_tod_clock_ext(seed + 48);
|
||||||
|
|
||||||
/* initial seed of the ppno drng */
|
/* initial seed of the ppno drng */
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
|
||||||
&prng_data->ppnows, NULL, 0, seed, sizeof(seed));
|
&prng_data->ppnows, NULL, 0, seed, sizeof(seed));
|
||||||
if (ret < 0) {
|
|
||||||
prng_errorflag = PRNG_SEED_FAILED;
|
|
||||||
ret = -EIO;
|
|
||||||
goto outfree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if fips mode is enabled, generate a first block of random
|
/* if fips mode is enabled, generate a first block of random
|
||||||
bytes for the FIPS 140-2 Conditional Self Test */
|
bytes for the FIPS 140-2 Conditional Self Test */
|
||||||
if (fips_enabled) {
|
if (fips_enabled) {
|
||||||
prng_data->prev = prng_data->buf + prng_chunk_size;
|
prng_data->prev = prng_data->buf + prng_chunk_size;
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
||||||
&prng_data->ppnows,
|
&prng_data->ppnows,
|
||||||
prng_data->prev, prng_chunk_size, NULL, 0);
|
prng_data->prev, prng_chunk_size, NULL, 0);
|
||||||
if (ret < 0 || ret != prng_chunk_size) {
|
|
||||||
prng_errorflag = PRNG_GEN_FAILED;
|
|
||||||
ret = -EIO;
|
|
||||||
goto outfree;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -440,12 +403,8 @@ static int prng_sha512_reseed(void)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* do a reseed of the ppno drng with this bytestring */
|
/* do a reseed of the ppno drng with this bytestring */
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
|
||||||
&prng_data->ppnows, NULL, 0, seed, sizeof(seed));
|
&prng_data->ppnows, NULL, 0, seed, sizeof(seed));
|
||||||
if (ret) {
|
|
||||||
prng_errorflag = PRNG_RESEED_FAILED;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -463,12 +422,8 @@ static int prng_sha512_generate(u8 *buf, size_t nbytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PPNO generate */
|
/* PPNO generate */
|
||||||
ret = cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_GEN,
|
||||||
&prng_data->ppnows, buf, nbytes, NULL, 0);
|
&prng_data->ppnows, buf, nbytes, NULL, 0);
|
||||||
if (ret < 0 || ret != nbytes) {
|
|
||||||
prng_errorflag = PRNG_GEN_FAILED;
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIPS 140-2 Conditional Self Test */
|
/* FIPS 140-2 Conditional Self Test */
|
||||||
if (fips_enabled) {
|
if (fips_enabled) {
|
||||||
|
@ -494,7 +449,7 @@ static int prng_open(struct inode *inode, struct file *file)
|
||||||
static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
|
static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
|
||||||
size_t nbytes, loff_t *ppos)
|
size_t nbytes, loff_t *ppos)
|
||||||
{
|
{
|
||||||
int chunk, n, tmp, ret = 0;
|
int chunk, n, ret = 0;
|
||||||
|
|
||||||
/* lock prng_data struct */
|
/* lock prng_data struct */
|
||||||
if (mutex_lock_interruptible(&prng_data->mutex))
|
if (mutex_lock_interruptible(&prng_data->mutex))
|
||||||
|
@ -545,13 +500,9 @@ static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
|
||||||
*
|
*
|
||||||
* Note: you can still get strict X9.17 conformity by setting
|
* Note: you can still get strict X9.17 conformity by setting
|
||||||
* prng_chunk_size to 8 bytes.
|
* prng_chunk_size to 8 bytes.
|
||||||
*/
|
*/
|
||||||
tmp = cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
|
cpacf_kmc(CPACF_KMC_PRNG, prng_data->prngws.parm_block,
|
||||||
prng_data->buf, prng_data->buf, n);
|
prng_data->buf, prng_data->buf, n);
|
||||||
if (tmp < 0 || tmp != n) {
|
|
||||||
ret = -EIO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
prng_data->prngws.byte_counter += n;
|
prng_data->prngws.byte_counter += n;
|
||||||
prng_data->prngws.reseed_counter += n;
|
prng_data->prngws.reseed_counter += n;
|
||||||
|
|
|
@ -22,8 +22,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||||
{
|
{
|
||||||
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
|
||||||
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
||||||
unsigned int index;
|
unsigned int index, n;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* how much is already in the buffer? */
|
/* how much is already in the buffer? */
|
||||||
index = ctx->count & (bsize - 1);
|
index = ctx->count & (bsize - 1);
|
||||||
|
@ -35,9 +34,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||||
/* process one stored block */
|
/* process one stored block */
|
||||||
if (index) {
|
if (index) {
|
||||||
memcpy(ctx->buf + index, data, bsize - index);
|
memcpy(ctx->buf + index, data, bsize - index);
|
||||||
ret = cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize);
|
cpacf_kimd(ctx->func, ctx->state, ctx->buf, bsize);
|
||||||
if (ret != bsize)
|
|
||||||
return -EIO;
|
|
||||||
data += bsize - index;
|
data += bsize - index;
|
||||||
len -= bsize - index;
|
len -= bsize - index;
|
||||||
index = 0;
|
index = 0;
|
||||||
|
@ -45,12 +42,10 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
|
||||||
|
|
||||||
/* process as many blocks as possible */
|
/* process as many blocks as possible */
|
||||||
if (len >= bsize) {
|
if (len >= bsize) {
|
||||||
ret = cpacf_kimd(ctx->func, ctx->state, data,
|
n = len & ~(bsize - 1);
|
||||||
len & ~(bsize - 1));
|
cpacf_kimd(ctx->func, ctx->state, data, n);
|
||||||
if (ret != (len & ~(bsize - 1)))
|
data += n;
|
||||||
return -EIO;
|
len -= n;
|
||||||
data += ret;
|
|
||||||
len -= ret;
|
|
||||||
}
|
}
|
||||||
store:
|
store:
|
||||||
if (len)
|
if (len)
|
||||||
|
@ -66,7 +61,6 @@ int s390_sha_final(struct shash_desc *desc, u8 *out)
|
||||||
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
unsigned int bsize = crypto_shash_blocksize(desc->tfm);
|
||||||
u64 bits;
|
u64 bits;
|
||||||
unsigned int index, end, plen;
|
unsigned int index, end, plen;
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* SHA-512 uses 128 bit padding length */
|
/* SHA-512 uses 128 bit padding length */
|
||||||
plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
|
plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8;
|
||||||
|
@ -88,10 +82,7 @@ int s390_sha_final(struct shash_desc *desc, u8 *out)
|
||||||
*/
|
*/
|
||||||
bits = ctx->count * 8;
|
bits = ctx->count * 8;
|
||||||
memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
|
memcpy(ctx->buf + end - 8, &bits, sizeof(bits));
|
||||||
|
cpacf_kimd(ctx->func, ctx->state, ctx->buf, end);
|
||||||
ret = cpacf_kimd(ctx->func, ctx->state, ctx->buf, end);
|
|
||||||
if (ret != end)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
/* copy digest to out */
|
/* copy digest to out */
|
||||||
memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
|
memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
|
||||||
|
|
|
@ -234,11 +234,9 @@ static inline int cpacf_kmc(unsigned long func, void *param,
|
||||||
* @param: address of parameter block; see POP for details on each func
|
* @param: address of parameter block; see POP for details on each func
|
||||||
* @src: address of source memory area
|
* @src: address of source memory area
|
||||||
* @src_len: length of src operand in bytes
|
* @src_len: length of src operand in bytes
|
||||||
*
|
|
||||||
* Returns 0 for the query func, number of processed bytes for digest funcs
|
|
||||||
*/
|
*/
|
||||||
static inline int cpacf_kimd(unsigned long func, void *param,
|
static inline void cpacf_kimd(unsigned long func, void *param,
|
||||||
const u8 *src, long src_len)
|
const u8 *src, long src_len)
|
||||||
{
|
{
|
||||||
register unsigned long r0 asm("0") = (unsigned long) func;
|
register unsigned long r0 asm("0") = (unsigned long) func;
|
||||||
register unsigned long r1 asm("1") = (unsigned long) param;
|
register unsigned long r1 asm("1") = (unsigned long) param;
|
||||||
|
@ -251,8 +249,6 @@ static inline int cpacf_kimd(unsigned long func, void *param,
|
||||||
: [src] "+a" (r2), [len] "+d" (r3)
|
: [src] "+a" (r2), [len] "+d" (r3)
|
||||||
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD)
|
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KIMD)
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
|
|
||||||
return src_len - r3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -261,11 +257,9 @@ static inline int cpacf_kimd(unsigned long func, void *param,
|
||||||
* @param: address of parameter block; see POP for details on each func
|
* @param: address of parameter block; see POP for details on each func
|
||||||
* @src: address of source memory area
|
* @src: address of source memory area
|
||||||
* @src_len: length of src operand in bytes
|
* @src_len: length of src operand in bytes
|
||||||
*
|
|
||||||
* Returns 0 for the query func, number of processed bytes for digest funcs
|
|
||||||
*/
|
*/
|
||||||
static inline int cpacf_klmd(unsigned long func, void *param,
|
static inline void cpacf_klmd(unsigned long func, void *param,
|
||||||
const u8 *src, long src_len)
|
const u8 *src, long src_len)
|
||||||
{
|
{
|
||||||
register unsigned long r0 asm("0") = (unsigned long) func;
|
register unsigned long r0 asm("0") = (unsigned long) func;
|
||||||
register unsigned long r1 asm("1") = (unsigned long) param;
|
register unsigned long r1 asm("1") = (unsigned long) param;
|
||||||
|
@ -278,8 +272,6 @@ static inline int cpacf_klmd(unsigned long func, void *param,
|
||||||
: [src] "+a" (r2), [len] "+d" (r3)
|
: [src] "+a" (r2), [len] "+d" (r3)
|
||||||
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD)
|
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_KLMD)
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
|
|
||||||
return src_len - r3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,13 +344,10 @@ static inline int cpacf_kmctr(unsigned long func, void *param, u8 *dest,
|
||||||
* @dest_len: size of destination memory area in bytes
|
* @dest_len: size of destination memory area in bytes
|
||||||
* @seed: address of seed data
|
* @seed: address of seed data
|
||||||
* @seed_len: size of seed data in bytes
|
* @seed_len: size of seed data in bytes
|
||||||
*
|
|
||||||
* Returns 0 for the query func, number of random bytes stored in
|
|
||||||
* dest buffer for generate function
|
|
||||||
*/
|
*/
|
||||||
static inline int cpacf_ppno(unsigned long func, void *param,
|
static inline void cpacf_ppno(unsigned long func, void *param,
|
||||||
u8 *dest, long dest_len,
|
u8 *dest, long dest_len,
|
||||||
const u8 *seed, long seed_len)
|
const u8 *seed, long seed_len)
|
||||||
{
|
{
|
||||||
register unsigned long r0 asm("0") = (unsigned long) func;
|
register unsigned long r0 asm("0") = (unsigned long) func;
|
||||||
register unsigned long r1 asm("1") = (unsigned long) param;
|
register unsigned long r1 asm("1") = (unsigned long) param;
|
||||||
|
@ -374,8 +363,6 @@ static inline int cpacf_ppno(unsigned long func, void *param,
|
||||||
: [fc] "d" (r0), [pba] "a" (r1),
|
: [fc] "d" (r0), [pba] "a" (r1),
|
||||||
[seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PPNO)
|
[seed] "a" (r4), [slen] "d" (r5), [opc] "i" (CPACF_PPNO)
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
|
|
||||||
return dest_len - r3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -383,10 +370,8 @@ static inline int cpacf_ppno(unsigned long func, void *param,
|
||||||
* instruction
|
* instruction
|
||||||
* @func: the function code passed to PCC; see CPACF_KM_xxx defines
|
* @func: the function code passed to PCC; see CPACF_KM_xxx defines
|
||||||
* @param: address of parameter block; see POP for details on each func
|
* @param: address of parameter block; see POP for details on each func
|
||||||
*
|
|
||||||
* Returns 0.
|
|
||||||
*/
|
*/
|
||||||
static inline int cpacf_pcc(unsigned long func, void *param)
|
static inline void cpacf_pcc(unsigned long func, void *param)
|
||||||
{
|
{
|
||||||
register unsigned long r0 asm("0") = (unsigned long) func;
|
register unsigned long r0 asm("0") = (unsigned long) func;
|
||||||
register unsigned long r1 asm("1") = (unsigned long) param;
|
register unsigned long r1 asm("1") = (unsigned long) param;
|
||||||
|
@ -397,8 +382,6 @@ static inline int cpacf_pcc(unsigned long func, void *param)
|
||||||
:
|
:
|
||||||
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC)
|
: [fc] "d" (r0), [pba] "a" (r1), [opc] "i" (CPACF_PCC)
|
||||||
: "cc", "memory");
|
: "cc", "memory");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _ASM_S390_CPACF_H */
|
#endif /* _ASM_S390_CPACF_H */
|
||||||
|
|
Loading…
Reference in a new issue