Skip to content

Commit f4d3cf6

Browse files
holger-denglerhcahca
authored andcommitted
s390/crypto: Postpone the key split to key conversion
Store the input key material of paes-xts in a single key_blob structure. The split of the input key material is postponed to the key conversion. Split the key material only, if the returned protected keytype requires a second protected key. For clear key pairs, prepare a clearkey token for each key and convert them separately to protected keys. Store the concatenated conversion results as input key in the context. All other input keys are stored as is. Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Holger Dengler <dengler@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 20a5f64 commit f4d3cf6

File tree

1 file changed

+74
-25
lines changed

1 file changed

+74
-25
lines changed

arch/s390/crypto/paes_s390.c

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,40 @@ static inline int _key_to_kb(struct key_blob *kb,
118118
return 0;
119119
}
120120

121+
static inline int _xts_key_to_kb(struct key_blob *kb,
122+
const u8 *key,
123+
unsigned int keylen)
124+
{
125+
size_t cklen = keylen / 2;
126+
127+
memset(kb->keybuf, 0, sizeof(kb->keybuf));
128+
129+
switch (keylen) {
130+
case 32:
131+
case 64:
132+
/* clear key value, prepare pkey clear key tokens in keybuf */
133+
kb->key = kb->keybuf;
134+
kb->keylen = make_clrkey_token(key, cklen, kb->key);
135+
kb->keylen += make_clrkey_token(key + cklen, cklen,
136+
kb->key + kb->keylen);
137+
break;
138+
default:
139+
/* other key material, let pkey handle this */
140+
if (keylen <= sizeof(kb->keybuf)) {
141+
kb->key = kb->keybuf;
142+
} else {
143+
kb->key = kmalloc(keylen, GFP_KERNEL);
144+
if (!kb->key)
145+
return -ENOMEM;
146+
}
147+
memcpy(kb->key, key, keylen);
148+
kb->keylen = keylen;
149+
break;
150+
}
151+
152+
return 0;
153+
}
154+
121155
static inline void _free_kb_keybuf(struct key_blob *kb)
122156
{
123157
if (kb->key && kb->key != kb->keybuf
@@ -135,7 +169,7 @@ struct s390_paes_ctx {
135169
};
136170

137171
struct s390_pxts_ctx {
138-
struct key_blob kb[2];
172+
struct key_blob kb;
139173
struct paes_protkey pk[2];
140174
spinlock_t pk_lock;
141175
unsigned long fc;
@@ -415,8 +449,7 @@ static int xts_paes_init(struct crypto_skcipher *tfm)
415449
{
416450
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
417451

418-
ctx->kb[0].key = NULL;
419-
ctx->kb[1].key = NULL;
452+
ctx->kb.key = NULL;
420453
spin_lock_init(&ctx->pk_lock);
421454

422455
return 0;
@@ -426,24 +459,46 @@ static void xts_paes_exit(struct crypto_skcipher *tfm)
426459
{
427460
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
428461

429-
_free_kb_keybuf(&ctx->kb[0]);
430-
_free_kb_keybuf(&ctx->kb[1]);
462+
_free_kb_keybuf(&ctx->kb);
431463
}
432464

433465
static inline int __xts_paes_convert_key(struct s390_pxts_ctx *ctx)
434466
{
435467
struct paes_protkey pk0, pk1;
468+
size_t split_keylen;
469+
int rc;
436470

437471
pk0.len = sizeof(pk0.protkey);
438472
pk1.len = sizeof(pk1.protkey);
439473

440-
if (__paes_keyblob2pkey(ctx->kb[0].key, ctx->kb[0].keylen, &pk0) ||
441-
__paes_keyblob2pkey(ctx->kb[1].key, ctx->kb[1].keylen, &pk1))
474+
rc = __paes_keyblob2pkey(ctx->kb.key, ctx->kb.keylen, &pk0);
475+
if (rc)
476+
return rc;
477+
478+
switch (pk0.type) {
479+
case PKEY_KEYTYPE_AES_128:
480+
case PKEY_KEYTYPE_AES_256:
481+
/* second keytoken required */
482+
if (ctx->kb.keylen % 2)
483+
return -EINVAL;
484+
split_keylen = ctx->kb.keylen / 2;
485+
486+
rc = __paes_keyblob2pkey(ctx->kb.key + split_keylen,
487+
split_keylen, &pk1);
488+
if (rc)
489+
return rc;
490+
491+
if (pk0.type != pk1.type)
492+
return -EINVAL;
493+
break;
494+
default:
495+
/* unsupported protected keytype */
442496
return -EINVAL;
497+
}
443498

444499
spin_lock_bh(&ctx->pk_lock);
445-
memcpy(&ctx->pk[0], &pk0, sizeof(pk0));
446-
memcpy(&ctx->pk[1], &pk1, sizeof(pk1));
500+
ctx->pk[0] = pk0;
501+
ctx->pk[1] = pk1;
447502
spin_unlock_bh(&ctx->pk_lock);
448503

449504
return 0;
@@ -452,12 +507,11 @@ static inline int __xts_paes_convert_key(struct s390_pxts_ctx *ctx)
452507
static inline int __xts_paes_set_key(struct s390_pxts_ctx *ctx)
453508
{
454509
unsigned long fc;
510+
int rc;
455511

456-
if (__xts_paes_convert_key(ctx))
457-
return -EINVAL;
458-
459-
if (ctx->pk[0].type != ctx->pk[1].type)
460-
return -EINVAL;
512+
rc = __xts_paes_convert_key(ctx);
513+
if (rc)
514+
return rc;
461515

462516
/* Pick the correct function code based on the protected key type */
463517
fc = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PXTS_128 :
@@ -471,24 +525,19 @@ static inline int __xts_paes_set_key(struct s390_pxts_ctx *ctx)
471525
}
472526

473527
static int xts_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
474-
unsigned int xts_key_len)
528+
unsigned int in_keylen)
475529
{
476530
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
477-
unsigned int ckey_len, key_len;
478531
u8 ckey[2 * AES_MAX_KEY_SIZE];
532+
unsigned int ckey_len;
479533
int rc;
480534

481-
if (xts_key_len % 2)
535+
if ((in_keylen == 32 || in_keylen == 64) &&
536+
xts_verify_key(tfm, in_key, in_keylen))
482537
return -EINVAL;
483538

484-
key_len = xts_key_len / 2;
485-
486-
_free_kb_keybuf(&ctx->kb[0]);
487-
_free_kb_keybuf(&ctx->kb[1]);
488-
rc = _key_to_kb(&ctx->kb[0], in_key, key_len);
489-
if (rc)
490-
return rc;
491-
rc = _key_to_kb(&ctx->kb[1], in_key + key_len, key_len);
539+
_free_kb_keybuf(&ctx->kb);
540+
rc = _xts_key_to_kb(&ctx->kb, in_key, in_keylen);
492541
if (rc)
493542
return rc;
494543

0 commit comments

Comments
 (0)