IBM Crypto Education Community - Group home

Pervasive (DS) Encryption sample: Generate a secure AES CIPHER key

  

/* Rexx */
/* Pervasive (Data Set) Encryption: Step 6 of 10                     */
/*-------------------------------------------------------------------*/
/* - Create a skeleton AES CIPHER key.                               */
/* - Use it to generate a secure AES CIPHER key.                     */
/* - Store the key in the CKDS.                                      */
/* - Read the key label from the CKDS.                               */
/*                                                                   */
/* ICSF HCR77C1 and a CEX6C or higher is required to generate an     */
/* AES CIPHER key to use with CPACF.                                 */
/*-------------------------------------------------------------------*/
/* Instructions:                                                     */
/* - Update aes_key_label with your desired key label name           */
/*                                                                   */
/*      Note: An example key label naming scheme is                  */
/*              DATASET.<datasetname>.ENCRKEY.<seqno>                */
/*                                                                   */
/* - EXECUTE THIS CLIST FROM TSO                                     */
/*   (e.g. EX 'HLQ.MLD.LLQ(GENKEYC)')                                */
/*-------------------------------------------------------------------*/
signal on novalue;
aes_key_label = ,
   left('DATASET.EYSHA.ICSF.ENCRYPT.ME.ENCRKEY.00000002',64);
/*-------------------------------------------------------------------*/
/* Create a skeleton AES CIPHER key with key-usage XPRTCPAC that     */
/* allows export to CPACF protected key format. This skeleton will   */
/* be used in CSNBKGN2 to generate a secure AES CIPHER key.  There   */
/* are many other key-usage and key-mgmt keywords that may be        */
/* specified in the rule_array.                                      */
/* See the ICSF Application Programmer's Guide for more details.     */
/*-------------------------------------------------------------------*/
KTB2_rule_array_count = '00000005'x;
KTB2_rule_array       = 'INTERNAL'||,
                        'AES     '||,
                        'CIPHER  '||,
                        'XPRTCPAC'||,
                        'ANY-MODE' ;
CALL CSNBKTB2;
/*-------------------------------------------------------------------*/
/* Generate a 256-bit AES CIPHER key                                 */
/*-------------------------------------------------------------------*/
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 = '00000384'x;
KGN2_generated_key_id_1        = left(KTB2_target_key_token,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_key_label;
KRC2_key_token_length = KGN2_generated_key_id_1_length;
KRC2_key_token = ,
   substr(KGN2_generated_key_id_1,1,c2d(KGN2_generated_key_id_1_length));
Call CSNBKRC2;
/*-------------------------------------------------------------------*/
/* Read the key from the CKDS                                        */
/*-------------------------------------------------------------------*/
KRR2_rule_array_count = '00000000'x;
KRR2_rule_array       = '' ;
KRR2_key_label        = aes_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.             */
/* 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 = '000002D5'x;
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
  KTB2_target_key_token = ,
   substr(KTB2_target_key_token,1,c2d(KTB2_target_key_token_length));

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
 KGN2_generated_key_id_1 = ,
  substr(KGN2_generated_key_id_1,1,c2d(KGN2_generated_key_id_1_length));


RETURN ;

/* --------------------------------------------------------------- */
/* CSNBKRC2 - Key Record Create2                                   */
/*                                                                 */
/* Adds a key token to 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;

RETURN;

 

/* --------------------------------------------------------------- */
 

/* CSNBKRR2 - Key Record Read2 (CKDS)                              */
/*                                                                 */
/* Reads a fixed-length or variable-length key token from the 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_key_token_length = '000002D5'x;
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 'Secure CIPHER key label: ' strip(aes_key_label);
    say 'Secure CIPHER key token length: ' c2d(KRR2_key_token_length);
    say 'Secure CIPHER key token: ';
    say c2x(substr(KRR2_key_token,1,c2d(KRR2_key_token_length)));
    EXIT;
  END;

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