IBM Crypto Education Community

IBM Crypto Education Community

IBM Crypto Education Community

Join the IBM Crypto Education community to explore and understand IBM cryptography technology. This community is operated and maintained by the IBM Crypto Development team.

 View Only

Rexx Sample: HMAC Generation from a Clear Key

By Eysha Shirrine Powers posted Wed March 25, 2020 05:28 PM

  

/* 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

0 comments
31 views

Permalink