/* Rexx */
/* --------------------------------------------------------------- */
/* Symmetric Key Encryption/Decryption (CSNBSYE/CSNBSYD) using */
/* variable-length AES protected key */
/* */
/* - call Key Token Build2 (CSNBKTB2) to build variable-length */
/* AES CIPHER skeleton tokens that allow rewrapping with */
/* CPACF protected key */
/* - use skeleton tokens as inputs to Key Generate2 (CSNBKGN2) */
/* to generate a pair of encrypted AES CIPHER tokens; */
/* one for use in encryption, the other for use in decryption */
/* - add generated keys to the CKDS */
/* - use keys in SYE/SYD */
/* */
/* To use variable-length AES CIPHER key tokens in protected key */
/* operations requires ICSF HCR77C1 and CEX6C. */
/* */
/* See the ICSF Application Programmer's Guide for detailed */
/* information on the callable services used in this sample. */
/* --------------------------------------------------------------- */
SIGNAL ON NOVALUE ;
/*---------------------------------------------------*/
/* Build a skeleton variable-length AES CIPHER token */
/* for encryption only. */
/*---------------------------------------------------*/
KTB2_rule_array_count = '00000006'x ;
KTB2_rule_array = 'AES ' ||,
'CIPHER ' ||,
'INTERNAL' ||,
'ENCRYPT ' ||,
'GCM ' ||,
'XPRTCPAC' ; /* required for protected key */
CALL KTB2 ;
/* save skeleton token for use in KGN2 */
KGN2_genkey_id1 = KTB2_skeleton_token ;
/*---------------------------------------------------*/
/* Build a skeleton variable-length AES CIPHER token */
/* for decryption only. */
/*---------------------------------------------------*/
KTB2_rule_array_count = '00000006'x ;
KTB2_rule_array = 'AES ' ||,
'CIPHER ' ||,
'INTERNAL' ||,
'DECRYPT ' ||,
'GCM ' ||,
'XPRTCPAC' ; /* required for protected key */
CALL KTB2 ;
/* save skeleton token for use in KGN2 */
KGN2_genkey_id2 = KTB2_skeleton_token ;
/*---------------------------------------------------*/
/* Use skeleton tokens as inputs to KGN2 to generate */
/* a pair of AES CIPHER keys that can be used in */
/* protected-key CPACF encryption and decryption. */
/*---------------------------------------------------*/
KGN2_rule_array_count = '00000002'x ;
KGN2_rule_array = 'AES ' ||,
'OPOP ' ;
KGN2_clear_key_bit_length = d2c(256,4) ;
KGN2_key_type_1 = 'TOKEN ' ;
KGN2_key_type_2 = 'TOKEN ' ;
KGN2_genkey_id1_length = d2c(900,4) ;
KGN2_genkey_id1 = left(KGN2_genkey_id1,c2d(KGN2_genkey_id1_length));
KGN2_genkey_id2_length = d2c(900,4) ;
KGN2_genkey_id2 = left(KGN2_genkey_id2,c2d(KGN2_genkey_id2_length));
CALL KGN2 ;
/* write generated keys to CKDS */
KRC2_key_label = left('SAMPLE.AES.CIPHER.GCM.ENCRYPT',64) ;
KRC2_key_token_length = KGN2_genkey_id1_length ;
KRC2_key_token = KGN2_genkey_id1 ;
CALL KRC2 ;
KRC2_key_label = left('SAMPLE.AES.CIPHER.GCM.DECRYPT',64) ;
KRC2_key_token_length = KGN2_genkey_id2_length ;
KRC2_key_token = KGN2_genkey_id2 ;
CALL KRC2 ;
/* Use generated key in symmetric encryption */
SYE_rule_array_count = '00000004'x ;
SYE_rule_array = 'AES ' ||,
'GCM ' ||,
'KEYIDENT' ||,
'ONLY ' ;
SYE_key_id_length = '00000040'x ;
SYE_key_id = left('SAMPLE.AES.CIPHER.GCM.ENCRYPT',64) ;
SYE_block_size = '00000010'x ;
SYE_initial_vector_length = '00000010'x ;
SYE_initial_vector = '8EBFFE2B973B3121D3858699CB26AAC7'x ;
SYE_clear_text_length = '00000010'x ;
SYE_clear_text = '0123456789ABCDEF';
CALL SYE ;
/* Use generated key in symmetric decryption */
SYD_key_id_length = '00000040'x ;
SYD_key_id = left('SAMPLE.AES.CIPHER.GCM.DECRYPT',64) ;
CALL SYD ;
EXIT ;
/*-----------------------------------------------------------------*/
/* Key Token Build2 */
/*-----------------------------------------------------------------*/
KTB2:
/* initialize parameter list */
KTB2_rc = 'FFFFFFFF'x ;
KTB2_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
KTB2_clear_key_bit_length = '00000000'x ;
KTB2_clear_key_value = '' ;
KTB2_key_name_length = '00000000'x ;
KTB2_key_name = '' ;
KTB2_user_assoc_data_length = '00000000'x ;
KTB2_user_assoc_data = '' ;
KTB2_token_data_length = '00000000'x ;
KTB2_token_data = '' ;
KTB2_service_data_length = '00000000'x ;
KTB2_service_data = '' ;
KTB2_skeleton_token_length = d2c(725,4) ;
KTB2_skeleton_token = d2c(0,725) ;
/* call CSNBKTB2 */
ADDRESS LINKPGM 'CSNBKTB2' ,
'KTB2_rc' ,
'KTB2_rs' ,
'exit_data_length' ,
'exit_data' ,
'KTB2_rule_array_count' ,
'KTB2_rule_array' ,
'KTB2_clear_key_bit_length' ,
'KTB2_clear_key_value' ,
'KTB2_key_name_length' ,
'KTB2_key_name' ,
'KTB2_user_assoc_data_length' ,
'KTB2_user_assoc_data' ,
'KTB2_token_data_length' ,
'KTB2_token_data' ,
'KTB2_service_data_length' ,
'KTB2_service_data' ,
'KTB2_skeleton_token_length' ,
'KTB2_skeleton_token' ;
IF (KTB2_rc /= '00000000'x) THEN
DO ;
SAY 'KTB2 failed: rc =' c2x(KTB2_rc) 'rs =' c2x(KTB2_rs) ;
EXIT ;
END ;
ELSE
DO ;
SAY 'KTB2: rc =' c2x(KTB2_rc) 'rs =' c2x(KTB2_rs) ;
KTB2_skeleton_token = ,
substr(KTB2_skeleton_token,1,c2d(KTB2_skeleton_token_length)) ;
CALL PRINTBLK c2x(KTB2_skeleton_token), 64 ;
END ;
RETURN ;
/* --------------------------------------------------------------- */
/* Key Generate2 */
/* --------------------------------------------------------------- */
KGN2:
/* initialize parameter list */
KGN2_rc = 'FFFFFFFF'x ;
KGN2_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
KGN2_key_name_1_length = '00000000'x ;
KGN2_key_name_1 = '' ;
KGN2_key_name_2_length = '00000000'x ;
KGN2_key_name_2 = '' ;
KGN2_user_assoc_data_1_length = '00000000'x ;
KGN2_user_assoc_data_1 = '' ;
KGN2_user_assoc_data_2_length = '00000000'x ;
KGN2_user_assoc_data_2 = '' ;
KGN2_KEK_id1_length = '00000000'x ;
KGN2_KEK_id1 = '' ;
KGN2_KEK_id2_length = '00000000'x ;
KGN2_KEK_id2 = '' ;
/* call CSNBKGN2 */
ADDRESS LINKPGM 'CSNBKGN2' ,
'KGN2_rc' ,
'KGN2_rs' ,
'exit_data_length' ,
'exit_data' ,
'KGN2_rule_array_count' ,
'KGN2_rule_array' ,
'KGN2_clear_key_bit_length' ,
'KGN2_key_type_1' ,
'KGN2_key_type_2' ,
'KGN2_key_name_1_length' ,
'KGN2_key_name_1' ,
'KGN2_key_name_2_length' ,
'KGN2_key_name_2' ,
'KGN2_user_assoc_data_1_length' ,
'KGN2_user_assoc_data_1' ,
'KGN2_user_assoc_data_2_length' ,
'KGN2_user_assoc_data_2' ,
'KGN2_KEK_id1_length' ,
'KGN2_KEK_id1' ,
'KGN2_KEK_id2_length' ,
'KGN2_KEK_id2' ,
'KGN2_genkey_id1_length' ,
'KGN2_genkey_id1' ,
'KGN2_genkey_id2_length' ,
'KGN2_genkey_id2' ;
IF (KGN2_rc /= '00000000'x) THEN
DO ;
SAY 'KGN2: rc =' c2x(KGN2_rc) 'rs =' c2x(KGN2_rs) ;
EXIT ;
END ;
ELSE
DO ;
SAY 'KGN2: rc =' c2x(KGN2_rc) 'rs =' c2x(KGN2_rs) ;
/* generated key identifier 1 */
KGN2_genkey_id1 = ,
substr(KGN2_genkey_id1, 1, c2d(KGN2_genkey_id1_length)) ;
SAY 'KGN2 generated key 1 length:' c2x(KGN2_genkey_id1_length) ;
SAY 'KGN2 generated key 1:' ;
CALL PRINTBLK c2x(KGN2_genkey_id1), 64 ;
/* generated key identifier 2 */
KGN2_genkey_id2 = ,
substr(KGN2_genkey_id2, 1, c2d(KGN2_genkey_id2_length)) ;
SAY 'KGN2 generated key 2 length:' c2x(KGN2_genkey_id2_length) ;
SAY 'KGN2 generated key 2:' ;
CALL PRINTBLK c2x(KGN2_genkey_id2), 64 ;
END ;
RETURN ;
/*-------------------------------------------------------------------*/
/* Symmetric Key Encipher */
/*-------------------------------------------------------------------*/
SYE:
/* initialize parameter list */
SYE_rc = 'FFFFFFFF'x ;
SYE_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
SYE_key_parms_length = '0000000C'x ;
SYE_key_parms = copies('00'x,c2d(SYE_key_parms_length)) ;
SYE_chain_data_length = '00000040'x ;
SYE_chain_data = copies('00'x,c2d(SYE_chain_data_length)) ;
SYE_cipher_text_length = SYE_clear_text_length ;
SYE_cipher_text = copies('00'x,c2d(SYE_cipher_text_length)) ;
SYE_opt_data_length = '00000000'x ;
SYE_opt_data = '' ;
/* call CSNBSYE */
ADDRESS LINKPGM 'CSNBSYE' ,
'SYE_rc' ,
'SYE_rs' ,
'exit_data_length' ,
'exit_data' ,
'SYE_rule_array_count' ,
'SYE_rule_array' ,
'SYE_key_id_length' ,
'SYE_key_id' ,
'SYE_key_parms_length' ,
'SYE_key_parms' ,
'SYE_block_size' ,
'SYE_initial_vector_length' ,
'SYE_initial_vector' ,
'SYE_chain_data_length' ,
'SYE_chain_data' ,
'SYE_clear_text_length' ,
'SYE_clear_text' ,
'SYE_cipher_text_length' ,
'SYE_cipher_text' ,
'SYE_opt_data_length' ,
'SYE_opt_data' ;
IF (SYE_rc /= '00000000'x) THEN
DO ;
SAY 'SYE failed: rc =' c2x(SYE_rc) 'rs =' c2x(SYE_rs) ;
EXIT ;
END ;
ELSE
DO ;
SAY 'SYE cipher text length:' c2x(SYE_cipher_text_length) ;
SAY 'SYE cipher text:' c2x(SYE_cipher_text) ;
END ;
RETURN ;
/*-------------------------------------------------------------------*/
/* Symmetric Key Decipher */
/*-------------------------------------------------------------------*/
SYD:
/* initialize parameter list */
SYD_rc = 'FFFFFFFF'x ;
SYD_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;
exit_data = '' ;
SYD_rule_array_count = SYE_rule_array_count ;
SYD_rule_array = SYE_rule_array ;
SYD_key_parms_length = SYE_key_parms_length ;
SYD_key_parms = SYE_key_parms ;
SYD_block_size = SYE_block_size ;
SYD_initial_vector_length = SYE_initial_vector_length ;
SYD_initial_vector = SYE_initial_vector ;
SYD_chain_data_length = '00000040'x ;
SYD_chain_data = copies('00'x,c2d(SYD_chain_data_length)) ;
SYD_cipher_text_length = SYE_cipher_text_length ;
SYD_cipher_text = SYE_cipher_text ;
SYD_clear_text_length = SYD_cipher_text_length ;
SYD_clear_text = copies('00'x,c2d(SYD_clear_text_length)) ;
SYD_opt_data_length = SYE_opt_data_length ;
SYD_opt_data = SYE_opt_data ;
/* call CSNBSYD */
ADDRESS LINKPGM 'CSNBSYD' ,
'SYD_rc' ,
'SYD_rs' ,
'exit_data_length' ,
'exit_data' ,
'SYD_rule_array_count' ,
'SYD_rule_array' ,
'SYD_key_id_length' ,
'SYD_key_id' ,
'SYD_key_parms_length' ,
'SYD_key_parms' ,
'SYD_block_size' ,
'SYD_initial_vector_length' ,
'SYD_initial_vector' ,
'SYD_chain_data_length' ,
'SYD_chain_data' ,
'SYD_cipher_text_length' ,
'SYD_cipher_text' ,
'SYD_clear_text_length' ,
'SYD_clear_text' ,
'SYD_opt_data_length' ,
'SYD_opt_data' ;
IF (SYD_rc /= '00000000'x) THEN
SAY 'SYD failed: rc =' c2x(SYD_rc) 'rs =' c2x(SYD_rs) ;
ELSE
DO ;
SAY 'SYD clear text length:' c2x(SYD_clear_text_length) ;
SAY 'SYD clear text:' SYD_clear_text ;
IF SYD_clear_text = SYE_clear_text THEN
SAY '***** DECIPHERED TEXT MATCHES CLEAR TEXT *****' ;
END ;
RETURN ;
/*-------------------------------------------------------------------*/
/* Key Record Create2 */
/*-------------------------------------------------------------------*/
KRC2:
/* initialize parameter list */
KRC2_rc = 'FFFFFFFF'x ;
KRC2_rs = 'FFFFFFFF'x ;
exit_data_length = '00000000'x ;\
exit_data = '' ;
KRC2_rule_array_count = '00000000'x ;
KRC2_rule_array = '' ;
/* call CSNBKRC2 */
ADDRESS LINKPGM 'CSNBKRC2' ,
'KRC2_rc' ,
'KRC2_rs' ,
'exit_data_length' ,
'exit_data' ,
'KRC2_rule_array_count' ,
'KRC2_rule_array' ,
'KRC2_key_label' ,
'KRC2_key_token_length' ,
'KRC2_key_token' ;
If (KRC2_rc /= '00000000'x) THEN
DO ;
SAY 'KRC2 failed: rc =' c2x(KRC2_rc) 'rs =' c2x(KRC2_rs) ;
EXIT ;
END ;
RETURN ;
/* --------------------------------------------------------------- */
/* PRINTBLK */
/* */
/* Print hex data in specified chunks. */
/* --------------------------------------------------------------- */
PRINTBLK:
arg data, max ;
/* The maximum length of an output line */
line_length = max ;
data_length = LENGTH(data) ;
num_lines = data_length % line_length ;
/* Parse the data */
IF data_length // line_length <> 0 THEN num_lines = num_lines + 1 ;
index = 1 ;
DO num_lines ;
SAY substr(data,index,line_length) ;
index = index + line_length ;
END ;
RETURN ;
/* --------------------------------------------------------------- */
/* Debug */
/* --------------------------------------------------------------- */
NOVALUE:
Say "Condition NOVALUE was raised." ;
Say CONDITION("D") "variable was not initialized." ;
Say SOURCELINE(sigl) ;
EXIT ;