@@ -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+
121155static 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
137171struct 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
433465static 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)
452507static 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
473527static 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