/* Rexx */
/* Sample: HMAC Generation from a Clear Key */
/*-------------------------------------------------------------------*/
/* Description: */
/* */
/* This REXX contains samples that show the following process: */
/* - Build a key token from a clear HMAC key */
/* - Generate a verification pattern */
/* - Import the clear HMAC key to become a secure key */
/* - Verify the key after import */
/* - Generate an HMAC */
/* */
/* How To Run: */
/* - Execute this script from TSO */
/* (e.g. EX 'HLQ.MLD.LLQ(HMGTEST1)') */
/*-------------------------------------------------------------------*/
signal on novalue;
/*********************************************************************/
/* Create the HMAC key */
/*********************************************************************/
clear_key_len = '00000028'x; /* 40 bytes */
clear_key_bit_len = '00000140'x; /* 320 bits */
clear_key_material = '49DB4DF5EC63FBE03D9659B6750DF562B641C579'x ||,
'D072C0177552288ED43D53987E049B5543D02FEC'x;
say "clear key material: " c2x(clear_key_material);
/* Build a clear HMAC key token */
ktb2_rule_count = '00000005'x ;
ktb2_rule_array = 'INTERNAL' ||,
'HMAC ' ||,
'KEY-CLR ' ||,
'MAC ' ||,
'GENERATE';
ktb2_key_bit_len = clear_key_bit_len;
ktb2_key_value = clear_key_material;
Call CSNBKTB2;
clear_key = substr(ktb2_target_key, 1, c2d(ktb2_target_key_len));
say "clear key: " c2x(clear_key);
/* Generate a verification pattern */
kyt2_rule_count = '00000002'x;
kyt2_rule_array = 'HMAC ' ||,
'GENERATE';
kyt2_key_id_length = ktb2_target_key_len;
kyt2_key_id = ktb2_target_key;
kyt2_ver_pattern_length = '00000008'x;
kyt2_ver_pattern = copies('00'x,8);
Call CSNBKYT2;
say 'KTB key verification pattern: ' c2x(kyt2_ver_pattern)
/* Build an internal HMAC skeleton key token */
ktb2_rule_count = '00000004'x ;
ktb2_rule_array = 'Internal' ||,
'HMAC ' ||,
'MAC ' ||,
'GENERATE';
ktb2_key_bit_len = '00000000'x ;
ktb2_key_value = '';
Call CSNBKTB2;
skeleton_key = substr(ktb2_target_key, 1, c2d(ktb2_target_key_len));
say "skeleton key: " c2x(skeleton_key);
/* Import the HMAC key material */
/* First Part */
kpi2_rule_count = '00000003'x;
kpi2_rule_array = 'HMAC ' ||,
'FIRST ' ||,
'MIN1PART';
kpi2_key_part_bit_len = clear_key_bit_len;
kpi2_key_part = clear_key_material;
kpi2_key_id_len = '000002D5'x ; /* max = 725 */
kpi2_key_id = ktb2_target_key;
Call CSNBKPI2;
secure_key = substr(kpi2_key_id, 1, c2d(kpi2_key_id_len));
say "secure key (partial): " c2x(secure_key);
/* Last Part */
kpi2_rule_count = '00000002'x;
kpi2_rule_array = 'HMAC ' ||,
'COMPLETE';
kpi2_key_part_bit_len = '00000000'x;
kpi2_key_part = '';
Call CSNBKPI2;
secure_key = substr(kpi2_key_id, 1, c2d(kpi2_key_id_len));
say "secure key (complete): " c2x(secure_key);
say "secure key length: " c2d(kpi2_key_id_len) "bytes";
/* Verify the imported key */
kyt2_rule_count = '00000002'x;
kyt2_rule_array = 'HMAC ' ||,
'VERIFY ';
kyt2_key_id_length = kpi2_key_id_len;
kyt2_key_id = kpi2_key_id;
Call CSNBKYT2;
if KYT2_rc = '00000000'x then
say "~ Verification Successful ~"
say 'KPI key verification pattern: ' c2x(kyt2_ver_pattern)
/*********************************************************************/
/* Generate the HMAC */
/*********************************************************************/
text = "Hello World"
text_len = '0000000B'x;
hmg_rule_count = '00000002'x;
hmg_rule_array = 'HMAC ' ||,
'SHA-1 ';
hmg_key_id_len = kpi2_key_id_len;
hmg_key_id = kpi2_key_id;
hmg_text_length = text_len;
hmg_text = text;
hmg_hmac_length = '00000014'x; /* 20 bytes for SHA-1 */
hmg_hmac = copies('00'x,c2d(hmg_hmac_Length));
Call CSNBHMG;
say "HMAC: " c2x(hmg_hmac);
say "-----------------------------------------------------------------"
say "End of Sample"
say "-----------------------------------------------------------------"
ExitScript:
Exit;
/* --------------------------------------------------------------- */
/* CSNBKTB2 - Key Token Build2 */
/* */
/* Builds a variable-length CCA symmetric key token to be used as */
/* input for the key generate (CSNBKGN2), key part import */
/* (CSNBKPI2), secure key import (CSNBSKI2) or diversified key */
/* generate (CSNBDKG2) callable service. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKTB2:
ktb2_rc = 'FFFFFFFF'x ;
ktb2_RS = 'FFFFFFFF'x ;
ktb2_exit_length = '00000000'x ;
ktb2_exit_data = '' ;
ktb2_key_name_len = '00000000'x ; /* 0 or 64 */
ktb2_key_name = '';
ktb2_UAD_len = '00000000'x ; /* 0 to 256 */
ktb2_UAD = '' ;
ktb2_token_data_len = '00000000'x ; /* must be 0 */
ktb2_token_data = '' ; /* ignored */
ktb2_reserved_len = '00000000'x ; /* must be 0 */
ktb2_reserved = '' ; /* ignored */
ktb2_target_key_len = '000002D5'x ; /* max = 725 */
ktb2_target_key = copies('00'x, 725);
address linkpgm 'CSNBKTB2' ,
'ktb2_rc' 'ktb2_rs' ,
'ktb2_exit_length' 'ktb2_exit_data' ,
'ktb2_rule_count' 'ktb2_rule_array' ,
'ktb2_key_bit_len' 'ktb2_key_value' ,
'ktb2_key_name_len' 'ktb2_key_name' ,
'ktb2_UAD_len' 'ktb2_UAD' ,
'ktb2_token_data_len' 'ktb2_token_data' ,
'ktb2_reserved_len' 'ktb2_reserved' ,
'ktb2_target_key_len' 'ktb2_target_key' ;
if (ktb2_rc /= '00000000'x) Then
do;
say 'KTB2 Failed (rc=' c2x(ktb2_rc)' rs='c2x(ktb2_rs)')' ;
signal ExitScript;
end;
Return;
/* --------------------------------------------------------------- */
/* CSNBKPI2 - Key Part Import2 */
/* */
/* Combine the clear key pars of any key type and return the */
/* combined key value. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKPI2:
kpi2_rc = 'FFFFFFFF'x ;
kpi2_rs = 'FFFFFFFF'x ;
kpi2_exit_length = '00000000'x ;
kpi2_exit_data = '' ;
address linkpgm 'CSNBKPI2' ,
'kpi2_rc' 'kpi2_rs' ,
'kpi2_exit_length' 'kpi2_exit_data' ,
'kpi2_rule_count' 'kpi2_rule_array' ,
'kpi2_key_part_bit_len' 'kpi2_key_part' ,
'kpi2_key_id_len' 'kpi2_key_id' ;
if (kpi2_rc /= '00000000'x) Then
do;
say 'KPI2 Failed (rc=' c2x(kpi2_rc)' rs='c2x(kpi2_rs)')' ;
signal ExitScript;
end;
Return;
/* --------------------------------------------------------------- */
/* CSNBHMG - HMAC Generate */
/* */
/* Generate a keyed hash message authentication code for the text */
/* string provided as input. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBHMG:
hmg_rc = 'FFFFFFFF'x ;
hmg_rs = 'FFFFFFFF'x ;
hmg_exit_length = '00000000'x;
hmg_exit_data = '';
hmg_chain_vector_length = '00000080'x;
hmg_chain_vector = copies('00'x,128);
address linkpgm 'CSNBHMG',
'hmg_rc' 'hmg_rs' ,
'hmg_exit_length' 'hmg_exit_data' ,
'hmg_rule_count' 'hmg_rule_array' ,
'hmg_key_id_len' 'hmg_key_id' ,
'hmg_text_length' 'hmg_text' ,
'hmg_chain_vector_length' 'hmg_chain_vector' ,
'hmg_hmac_length' 'hmg_hmac' ;
if (hmg_rc /= '00000000'x) Then
do;
say 'HMG Failed (rc=' c2x(hmg_rc)' rs='c2x(hmg_rs)')' ;
signal ExitScript;
end;
Return;
/* --------------------------------------------------------------- */
/* Call CSNBKYT2 */
/* */
/* Generate or verify a secure, cryptographic verification pattern */
/* for keys. */
/* */
/* See the ICSF Application Programmer's Guide for more details. */
/* --------------------------------------------------------------- */
CSNBKYT2:
kyt2_rc = 'FFFFFFFF'x;
kyt2_rs = 'FFFFFFFF'x;
kyt2_exit_data_length = '00000000'x;
kyt2_exit_data = '';
kyt2_kek_id_length = '00000000'x;
kyt2_kek_id = '';
kyt2_reserved_length = '00000000'x;
kyt2_reserved = '';
ADDRESS LINKPGM "CSNBKYT2",
'kyt2_rc' 'kyt2_rs' ,
'kyt2_exit_length' 'kyt2_exit_data' ,
'kyt2_rule_count' 'kyt2_rule_array' ,
'kyt2_key_id_length' 'kyt2_key_id' ,
'kyt2_kek_id_length' 'kyt2_kek_id' ,
'kyt2_reserved_length' 'kyt2_reserved' ,
'kyt2_ver_pattern_length' 'kyt2_ver_pattern';
if (kyt2_RC /= '00000000'x) Then
do;
say 'KYT2 Failed (rc=' c2x(kyt2_rc)' rs='c2x(kyt2_rs)')' ;
signal ExitScript;
end;
return;
/* --------------------------------------------------------------- */
/* Debug ;-) */
/* --------------------------------------------------------------- */
NOVALUE:
Say "Condition NOVALUE was raised."
Say CONDITION("D") "variable was not initialized."
Say SOURCELINE(sigl)
Exit