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

Use Diversified Key Generate2 to derive an AES CIPHER key

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

  

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

0 comments
9 views

Permalink