/* Rexx */
/*--------------------------------------------------------------------*/
/* This sample will use Key Export (CSNBKEX) and Key Import (CSNBKIM) */
/* and NOCV key-encrypting keys (aka transport keys) to create */
/* another key with the same clear key value. This will work with */
/* any key type supported by Key Import. */
/* */
/* To generate NOCV key-encrypting keys, see Rexx Sample in the */
/* IBM Crypto Education community: */
/* Generate/Create NOCV IMPORTER/EXPORTER key-encrypting key pair */
/* */
/* For more information about NOCV key-encrypting keys (KEKs), see */
/* Chapter 2 of the z/OS ICSF Application Programmer's Guide. */
/*--------------------------------------------------------------------*/
/* When a key is exported under a NOCV KEK, the control vector is not */
/* applied to the transport key. The key is encrypted under the */
/* transport key itself, not under the transport key variant. */
/* For more information on transport key variants and the callable */
/* services used in this sample, see the z/OS ICSF Application */
/* Programmer's Guide. */
/*--------------------------------------------------------------------*/
/* This sample assumes the following key-encrypting keys exist */
/* in the CKDS. The EXPORTER and IMPORTER KEKs must have the */
/* same clear key value. */
NOCV_EXPORTER_KEK = left('SAMPLE.NOCV.EXPORTER',64) ;
NOCV_IMPORTER_KEK = left('SAMPLE.NOCV.IMPORTER',64) ;
/* This sample will create an IPINENC key from an existing */
/* double-length CIPHER key. The key length of both keys must */
/* be the same. The IPINENC key will have the same clear key */
/* value as the CIPHER key. */
key_label_to_be_exported = left('SAMPLE.CIPHER',64) ;
/* Call Key Test2 to generate a key check value (kcv) for the */
/* key to be exported. This kcv will be used later to verify */
/* that both CIPHER and IPINENC keys have the same key value. */
/* Key Test2 parameters */
rule_array_count = '00000003'x ;
rule_array = 'DES '||,
'GENERATE'||, /* generate kcv */
'ENC-ZERO' ;
key_identifier_length = '00000040'x ;
key_identifier = key_label_to_be_exported ; /* SAMPLE.CIPHER */
verification_pattern_length = '00000008'x ;
verification_pattern = '0000000000000000'x ;
CALL KYT2 ;
CIPHER_kcv = verification_pattern ; /* save kcv */
SAY 'CIPHER KCV:' c2x(CIPHER_kcv) ;
/* KEY EXPORT (CSNBKEX) will unwrap the source key from */
/* encryption under the DES master key to encryption under the */
/* exporter key-encrypting key. All wrapping/unwrapping of */
/* secure keys are performed inside the secure boundary of the */
/* crypto coprocessor. */
/* Key Export parameter list */
KEX_rc = 'FFFFFFFF'x ;
KEX_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
key_type = 'CIPHER ' ;
source_key_identifier = key_label_to_be_exported ;
exporter_key_identifier = NOCV_EXPORTER_KEK ;
target_key_identifier = copies('00'x,64) ;
/* call Key Export */
ADDRESS LINKPGM 'CSNBKEX' ,
'KEX_rc' ,
'KEX_rs' ,
'exit_data_length' ,
'exit_data' ,
'key_type' ,
'source_key_identifier' ,
'exporter_key_identifier' ,
'target_key_identifier' ;
if KEX_rc /= '00000000'x THEN
DO ;
SAY 'KEX failed: rc =' c2x(KEX_rc) 'rs =' c2x(KEX_rs) ;
EXIT ;
END ;
ELSE
DO ;
SAY 'exported key identifier:' ;
SAY c2x(substr(target_key_identifier, 1,32)) ;
SAY c2x(substr(target_key_identifier,33,32)) ;
END ;
/* KEY IMPORT (CSNBKIM) will unwrap the source key from */
/* encryption under the key-encrypting key to encryption */
/* under the DES master key. */
/* Key Import parameter list */
KIM_rc = 'FFFFFFFF'x ;
KIM_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
key_type = 'IPINENC' ; /* must specify a key type,
TOKEN not allowed */
source_key_identifier = target_key_identifier ; /* from KEX */
importer_key_identifier = NOCV_IMPORTER_KEK ;
target_key_identifier = copies('00'x,64) ;
/* call Key Import */
ADDRESS LINKPGM 'CSNBKIM' ,
'KIM_rc' ,
'KIM_rs' ,
'exit_data_length' ,
'exit_data' ,
'key_type' ,
'source_key_identifier' ,
'importer_key_identifier' ,
'target_key_identifier' ;
IF KIM_rc /= '00000000'x THEN
DO ;
SAY 'KIM failed: rc =' c2x(KIM_rc) 'rs =' c2x(KIM_rs) ;
EXIT ;
END ;
ELSE
DO ;
SAY 'imported key identifier:' ;
SAY c2x(substr(target_key_identifier, 1,32)) ;
SAY c2x(substr(target_key_identifier,33,32)) ;
END ;
/* The imported key identifier is now encrypted under the */
/* DES master key. Write the imported key token to the CKDS. */
/* Key Record Create2 parameter list */
KRC2_rc = 'FFFFFFFF'x ;
KRC2_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
rule_array_count = '00000000'x ;
rule_array = '' ;
key_label = left('SAMPLE.IPINENC',64) ;
key_token_length = '00000040'x ;
key_token = target_key_identifier ; /* from KIM */
/* call CKDS Key Record Create2 */
ADDRESS LINKPGM 'CSNBKRC2',
'KRC2_rc' ,
'KRC2_rs' ,
'exit_data_length' ,
'exit_data' ,
'rule_array_count' ,
'rule_array' ,
'key_label' ,
'key_token_length' ,
'key_token' ;
IF KRC2_rc /= '00000000'x THEN
DO ;
SAY 'KRC2 failed: rc =' c2x(KRC2_rc) 'rs =' c2x(KRC2_rs) ;
EXIT ;
END ;
/* Call Key Test2 to verify that the kcv of the */
/* CIPHER key matches the kcv of the IPINENC key. */
/* Key Test2 parameters */
rule_array_count = '00000003'x ;
rule_array = 'DES '||,
'VERIFY '||, /* verify kcv */
'ENC-ZERO' ;
key_identifier_length = '00000040'x ;
key_identifier = left('SAMPLE.IPINENC',64) ;
verification_pattern_length = '00000008'x ;
verification_pattern = CIPHER_kcv ;
CALL KYT2 ;
IF KYT2_rc = '00000000'x THEN
SAY 'KCVs MATCH!!!' ;
EXIT ;
/*--------------------------------------------------------*/
/* Use Key Test2 to generate or verify a key check value. */
/*--------------------------------------------------------*/
KYT2:
/* Key Test2 parameters */
KYT2_rc = 'FFFFFFFF'x ;
KYT2_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
key_encrypting_key_identifier_length = '00000000'x ;
key_encrypting_key_identifier = '' ;
reserved_length = '00000000'x ;
reserved = '' ;
/* call Key Test2 */
ADDRESS LINKPGM 'CSNBKYT2',
'KYT2_rc' ,
'KYT2_rs' ,
'exit_data_length' ,
'exit_data' ,
'rule_array_count' ,
'rule_array' ,
'key_identifier_length' ,
'key_identifier' ,
'key_encrypting_key_identifier_length' ,
'key_encrypting_key_identifier' ,
'reserved_length' ,
'reserved' ,
'verification_pattern_length' ,
'verification_pattern' ;
IF KYT2_rc /= '00000000'x THEN
DO ;
SAY 'KYT2 failed: rc =' c2x(KYT2_rc) 'rs =' c2x(KYT2_rs) ;
EXIT ;
END ;
RETURN ;