/* Rexx */
/*-------------------------------------------------------------------*/
/* This sample testcase will use Diversified Key Generate2 (CSNBDKG2)*/
/* to derive an operational AES CIPHER key. */
/* */
/* - Use CSNBKTB2 to create a skeleton AES DKYGENKY DKYL0 D-ALL key. */
/* - Use CSNBKTB2 to create a skeleton AES CIPHER key. */
/* - Use CSNBKGN2 and skeleton AES DKYGENKY to generate a secure */
/* AES DKYGENKY key. */
/* - Use CSNBKRC2 to store secure AES DKYGENKY key in CKDS. */
/* - Use CSNBDKG2, DKYGENKY key label and skeleton CIPHER key to */
/* generate a secure AES CIPHER key. */
/* - Use CSNBKRC2 to store secure AES CIPHER key in CKDS. */
/*-------------------------------------------------------------------*/
/* See the ICSF Application Programmer's Guide for more information */
/* on the callable services used in this sample testcase. */
/*-------------------------------------------------------------------*/
signal on novalue;
AES_DKYGENKY_key_label = left('SAMPLE.AES.DKYGENKY.DKYL0.DALL',64);
AES_CIPHER_key_label = left('SAMPLE.AES.CIPHER',64);
/*-------------------------------------------------------------------*/
/* Create a skeleton AES DKYGENKY. This skeleton will be used in */
/* CSNBKGN2 to generate a secure AES DKYGENKY key. */
/*-------------------------------------------------------------------*/
KTB2_rule_array_count = '00000005'x;
KTB2_rule_array = 'INTERNAL'||,
'AES '||,
'DKYGENKY'||,
'D-ALL '||, /* can generate any key type */
'DKYL0 ';
CALL CSNBKTB2;
AES_DKYGENKY_skeleton = KTB2_target_key_token ;
/*-------------------------------------------------------------------*/
/* Create a skeleton AES CIPHER key. This skeleton will be used in */
/* CSNBDKG2 to generate a secure AES CIPHER key. */
/*-------------------------------------------------------------------*/
KTB2_rule_array_count = '00000003'x;
KTB2_rule_array = 'INTERNAL'||,
'AES '||,
'CIPHER ';
CALL CSNBKTB2;
AES_CIPHER_skeleton = KTB2_target_key_token ;
/*-------------------------------------------------------------------*/
/* Generate a secure 256-bit AES DKYGENKY DKYLO D-ALL to be used */
/* in CSNBDKG2. */
/*-------------------------------------------------------------------*/
KGN2_rule_array_count = '00000002'x;
KGN2_rule_array = 'AES '||,
'OP ';
KGN2_clear_bit_length = '00000100'x; /* 256-bit */
KGN2_key_type_1 = 'TOKEN ';
KGN2_key_type_2 = '';
KGN2_generated_key_id_1_length = d2c(900,4);
KGN2_generated_key_id_1 = left(AES_DKYGENKY_skeleton,900);
KGN2_generated_key_id_2_length = '00000000'x;
KGN2_generated_key_id_2 = '';
CALL CSNBKGN2;
/*-------------------------------------------------------------------*/
/* Store the key in the CKDS. */
/*-------------------------------------------------------------------*/
KRC2_key_label = AES_DKYGENKY_key_label;
KRC2_key_token_length = KGN2_generated_key_id_1_length;
KRC2_key_token = KGN2_generated_key_id_1;
CALL CSNBKRC2;
/*-------------------------------------------------------------------*/
/* Use the secure DKYGENKY to derive a secure AES CIPHER key. */
/*-------------------------------------------------------------------*/
DKG2_rule_array_count = '00000001'x;
DKG2_rule_array = 'KDFFM-DK' ;
DKG2_generating_key_id_length = d2c(64,4);
DKG2_generating_key_id = AES_DKYGENKY_key_label;
DKG2_derivation_data_length = '00000010'x;
DKG2_derivation_data = '1234567890123456';
DKG2_generated_key_id_1_length = d2c(725,4);
DKG2_generated_key_id_1 = left(AES_CIPHER_skeleton,725);
CALL CSNBDKG2;
/*-------------------------------------------------------------------*/
/* Store the key in the CKDS. */
/*-------------------------------------------------------------------*/
KRC2_key_label = AES_CIPHER_key_label;
KRC2_key_token_length = DKG2_generated_key_id_1_length;
KRC2_key_token = DKG2_generated_key_id_1;
CALL CSNBKRC2;
/*-------------------------------------------------------------------*/
/* Read the key records from the CKDS. */
/*-------------------------------------------------------------------*/
KRR2_key_label = AES_CIPHER_key_label;
CALL CSNBKRR2;
KRR2_key_label = AES_DKYGENKY_key_label;
CALL CSNBKRR2;
SAY "-----------------------------------------------------------------"
SAY "End of Sample"
SAY "-----------------------------------------------------------------"
EXIT;
/* --------------------------------------------------------------- */
/* CSNBKTB2 - Key Token Build2 */
/* */
/* Build a skeleton token to use as input to CSNBKGN2 and CSNBDKG2.*/
/* Returns a variable-length skeleton token. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKTB2:
KTB2_rc = 'FFFFFFFF'x;
KTB2_rs = 'FFFFFFFF'x;
KTB2_exit_data_length = '00000000'x;
KTB2_exit_data = '';
KTB2_clear_key_bit_length = '00000000'x;
KTB2_clear_key_value = '';
KTB2_key_name_length = '00000000'x;
KTB2_key_name = '';
KTB2_user_data_length = '00000000'x;
KTB2_user_data = '';
KTB2_token_data_length = '00000000'x;
KTB2_token_data = '';
KTB2_service_data_length = '00000000'x;
KTB2_service_data = '';
KTB2_target_key_token_length = d2c(725,4);
KTB2_target_key_token = copies('00'x,725);
ADDRESS linkpgm 'CSNBKTB2',
'KTB2_rc' 'KTB2_rs' ,
'KTB2_exit_data_length' 'KTB2_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_data_length' 'KTB2_user_data' ,
'KTB2_token_data_length' 'KTB2_token_data' ,
'KTB2_service_data_length' 'KTB2_service_data' ,
'KTB2_target_key_token_length' 'KTB2_target_key_token';
IF KTB2_rc /= '00000000'x THEN
DO;
SAY 'KTB2 Failed (rc=' c2x(KTB2_rc)' rs='c2x(KTB2_rs)')';
EXIT;
END;
ELSE
DO;
KTB2_target_key_token = ,
substr(KTB2_target_key_token,1,c2d(KTB2_target_key_token_length));
SAY 'KTB2 target_key_token_length:' ,
c2x(KTB2_target_key_token_length);
SAY 'KTB2 target_key_token:';
CALL PRINTBLK c2x(KTB2_target_key_token), 64;
END;
SAY;
RETURN;
/* --------------------------------------------------------------- */
/* CSNBKGN2 - Key Generate2 */
/* */
/* Generates either one or two HMAC or AES keys of specified */
/* key type. */
/* Returns a variable-length CCA key token. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKGN2:
KGN2_rc = 'FFFFFFFF'x;
KGN2_rs = 'FFFFFFFF'x;
KGN2_exit_data_length = '00000000'x;
KGN2_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_data_1_length = '00000000'x;
KGN2_user_data_1 = '';
KGN2_user_data_2_length = '00000000'x;
KGN2_user_data_2 = '';
KGN2_kek_id_1_length = '00000000'x;
KGN2_kek_id_1 = '';
KGN2_kek_id_2_length = '00000000'x;
KGN2_kek_id_2 = '';
ADDRESS linkpgm 'CSNBKGN2',
'KGN2_rc' 'KGN2_rs' ,
'KGN2_exit_data_length' 'KGN2_exit_data' ,
'KGN2_rule_array_count' 'KGN2_rule_array' ,
'KGN2_clear_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_data_1_length' 'KGN2_user_data_1' ,
'KGN2_user_data_2_length' 'KGN2_user_data_2' ,
'KGN2_kek_id_1_length' 'KGN2_kek_id_1' ,
'KGN2_kek_id_2_length' 'KGN2_kek_id_2' ,
'KGN2_generated_key_id_1_length' 'KGN2_generated_key_id_1',
'KGN2_generated_key_id_2_length' 'KGN2_generated_key_id_2';
IF KGN2_rc /= '00000000'x THEN
DO;
SAY 'KGN2 Failed (rc=' c2x(KGN2_rc)' rs='c2x(KGN2_rs)')';
EXIT;
END;
ELSE
DO;
KGN2_generated_key_id_1 = ,
substr(KGN2_generated_key_id_1,1,c2d(KGN2_generated_key_id_1_length));
SAY 'KGN2 generated_key_id_1_length:' ,
c2x(KGN2_generated_key_id_1_length);
SAY 'KGN2 generated_key_id_1:';
CALL PRINTBLK c2x(KGN2_generated_key_id_1), 64;
END;
SAY;
RETURN;
/* --------------------------------------------------------------- */
/* CSNBDKG2 - Diversified Key Generate2 */
/* */
/* Generates an AES key based on a function of the key_generating */
/* key, the process rule, and data supplied. */
/* Returns a variable-length CCA key token. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBDKG2:
DKG2_rc = 'FFFFFFFF'x;
DKG2_rs = 'FFFFFFFF'x;
DKG2_exit_data_length = '00000000'x;
DKG2_exit_data = '';
DKG2_reserved1_length = '00000000'x;
DKG2_reserved1 = '';
DKG2_reserved2_length = '00000000'x;
DKG2_reserved2 = '';
DKG2_generated_key_id_2_length = '00000000'x;
DKG2_generated_key_id_2 = '';
ADDRESS linkpgm 'CSNBDKG2',
'DKG2_rc' 'DKG2_rs' ,
'DKG2_exit_data_length' 'DKG2_exit_data' ,
'DKG2_rule_array_count' 'DKG2_rule_array' ,
'DKG2_generating_key_id_length' 'DKG2_generating_key_id' ,
'DKG2_derivation_data_length' 'DKG2_derivation_data' ,
'DKG2_reserved1_length' 'DKG2_reserved1' ,
'DKG2_reserved2_length' 'DKG2_reserved2' ,
'DKG2_generated_key_id_1_length' 'DKG2_generated_key_id_1',
'DKG2_generated_key_id_2_length' 'DKG2_generated_key_id_2';
IF DKG2_rc /= '00000000'x THEN
DO;
SAY 'DKG2 Failed (rc=' c2x(DKG2_rc)' rs='c2x(DKG2_rs)')';
EXIT;
END;
ELSE
DO;
DKG2_generated_key_id_1 = ,
substr(DKG2_generated_key_id_1,1,c2d(DKG2_generated_key_id_1_length));
SAY 'DKG2 generated_key_id_1_length:' ,
c2x(KGN2_generated_key_id_1_length);
SAY 'DKG2 generated_key_id_1:';
CALL PRINTBLK c2x(DKG2_generated_key_id_1), 64;
END;
SAY;
RETURN;
/* --------------------------------------------------------------- */
/* CSNBKRC2 - Key Record Create2 */
/* */
/* Creates a CKDS key record and writes the key to the CKDS. */
/* The key label must be unique in the CKDS. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKRC2:
KRC2_rc = 'FFFFFFFF'x;
KRC2_rs = 'FFFFFFFF'x;
KRC2_exit_data_length = '00000000'x;
KRC2_exit_data = '';
KRC2_rule_array_count = '00000000'x;
KRC2_rule_array = '';
ADDRESS LINKPGM 'CSNBKRC2',
'KRC2_rc',
'KRC2_rs',
'KRC2_exit_data_length',
'KRC2_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;
SAY;
RETURN;
/* --------------------------------------------------------------- */
/* CSNBKRR2 - Key Record Read2 */
/* */
/* Reads the CKDS key record from the in-storage CKDS. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKRR2:
KRR2_rc = 'FFFFFFFF'x;
KRR2_rs = 'FFFFFFFF'x;
KRR2_exit_data_length = '00000000'x;
KRR2_exit_data = '';
KRR2_rule_array_count = '00000000'x;
KRR2_rule_array = '';
KRR2_key_token_length = d2c(725,4);
KRR2_key_token = copies('00'x,725);
ADDRESS LINKPGM 'CSNBKRR2',
'KRR2_rc',
'KRR2_rs',
'KRR2_exit_data_length',
'KRR2_exit_data',
'KRR2_rule_array_count',
'KRR2_rule_array',
'KRR2_key_label',
'KRR2_key_token_length',
'KRR2_key_token';
IF KRR2_rc /= '00000000'x THEN
DO;
SAY 'KRR2 Failed (rc=' c2x(KRR2_rc)' rs='c2x(KRR2_rs)')';
EXIT;
END;
ELSE
DO ;
KRR2_key_token = substr(KRR2_key_token,1,c2d(KRR2_key_token_length));
SAY STRIP(KRR2_key_label);
SAY 'key token length:' c2x(KRR2_key_token_length);
CALL PRINTBLK c2x(KRR2_key_token), 64;
END;
SAY;
RETURN;
/* ----------------------------------------------------------------- */
/* PRINTBLK: */
/* */
/* Helper routine to display hex data with a fixed line length */
/* ----------------------------------------------------------------- */
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;