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: Archive a key in the CKDS

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

  

/* Rexx */

/* Sample: Archive a secure AES key                                  */
/*-------------------------------------------------------------------*/
/* Description:                                                      */
/*                                                                   */
/* This REXX contains samples that show how to archive an existing   */
/* key:                                                              */
/*  - Generate and store a 256-bit AES DATA key in the CKDS          */
/*  - Encrypt data using the AES key                                 */
/*  - Decrypt data using the AES key                                 */
/*  - Archive the key                                                */
/*  - Attempt to encrypt/decrypt data with archived key              */
/*                                                                   */
/* How To Run:                                                       */
/* - Execute this script from TSO                                    */
/*   (e.g. EX 'HLQ.MLD.LLQ(KEYARCH)')                                */
/*-------------------------------------------------------------------*/
signal on novalue;

/* CLEANUP labels in use for this sample */
aes_key_label = left('ICSF.KEYSAMP.AES256.KEY001',64);
krd_label = aes_key_label;
Call CSNBKRD;

/*********************************************************************/
/* Generate a 256-bit AES DATA key                                   */
/*********************************************************************/
kgn_key_form           = 'OP  ';
kgn_key_length         = 'KEYLN32 ';
kgn_key_type_1         = 'AESDATA ';
kgn_key_type_2         = '';
kgn_kek_identifier_1   = copies('00'x,64);
kgn_kek_identifier_2   = '';
kgn_generated_key_identifier_1 = copies('00'x,64);
kgn_generated_key_identifier_2 = '';
Call CSNBKGN;

say "aes secure key: " c2x(kgn_generated_key_identifier_1);

/*********************************************************************/
/* Store the key in the CKDS                                         */
/*********************************************************************/
krc2_label = aes_key_label;
krc2_token_length = '00000040'x;
krc2_token = kgn_generated_key_identifier_1;
Call CSNBKRC2;

/*********************************************************************/
/* Encrypt data using the secure key                                 */
/*********************************************************************/
sae_rule_array_count = '00000003'x;
sae_rule_array = 'AES     ' ||,
                 'PKCS-PAD' ||,
                 'KEYIDENT';
sae_key_identifier_length = '00000040'x;
sae_key_identifier = aes_key_label;
sae_init_vector_length = '00000010'x;
sae_init_vector = '11111111111111111111111111111111'x;
sae_block_size = '00000010'x;
sae_clear_text_length = '0000000B'x;
sae_clear_text = 'Secret Data';
sae_cipher_text_length = '00000010'x;
sae_cipher_text = copies('00'x, 16);
Call CSNBSAE;

encrypted_text = substr(sae_cipher_text, 1, c2d(sae_cipher_text_length));
say 'clear_text:     ' sae_clear_text;
say 'encrypted_text: ' c2x(encrypted_text);

/*********************************************************************/
/* Decrypt data using the secure key                                 */
/*********************************************************************/
sad_rule_array_count = sae_rule_array_count;
sad_rule_array = sae_rule_array;
sad_key_identifier_length = '00000040'x;
sad_key_identifier = aes_key_label;
sad_init_vector_length = sae_init_vector_length;
sad_init_vector = sae_init_vector;
sad_block_size = sae_block_size;
sad_cipher_text_length = sae_cipher_text_length;
sad_cipher_text = sae_cipher_text;
sad_clear_text_length = '00000010'x;
sad_clear_text = copies('00'x, 16);
Call CSNBSAD;

decrypted_text = substr(sad_clear_text, 1, c2d(sad_clear_text_length));
say 'decrypted_text: ' decrypted_text;

/*********************************************************************/
/* Archive the key                                                   */
/*********************************************************************/
KDMW_rule_array_count = '00000001'x;
KDMW_rule_array       = 'CKDS    ';
KDMW_label_count      = '00000001'x;
KDMW_label_list       = left(aes_key_label,72);
KDMW_metadata_list_length = '00000005'x;
KDMW_metadata_list    = '0005'x ||,          /* Length of structure  */
                        '0009'x ||,          /* Record archive flag  */
                        '01'x;               /* Turn ON the flag     */
KDMW_results_list     = copies('00'x,8);     /* 4-byte RC, 4-byte RS */
Call CSFKDMW;

/*********************************************************************/
/* Verify the key is archived                                        */
/*********************************************************************/
KDMR_rule_array_count = '00000001'x;
KDMR_rule_array       = 'CKDS    ';
KDMR_record_label     = left(aes_key_label,72);
KDMR_metadata_list_length = '00000004'x;
KDMR_metadata_list    = '0004'x ||,          /* Length of structure  */
                        '0009'x;             /* Record archive flag  */
KDMR_output_list_length = '00000005'x;
KDMR_output_list      = copies('00'x,5);
Call CSFKDMR;

output_block_length = substr(KDMR_output_list,1,2);
output_block_flag = substr(KDMR_output_list,3,1);
output_block_value = substr(KDMR_output_list,5,1);

say '';
if output_block_value = '01'x then
  say 'Key archived!';
else
  say 'Key not archived!';

/*********************************************************************/
/* Attempt to use the archived key                                   */
/*********************************************************************/
sae_clear_text_length = '0000000B'x;
sae_clear_text = 'Secret Data';
sae_cipher_text_length = '00000010'x;
sae_cipher_text = copies('00'x, 16);
say '';
say 'Attempt encryption...';
Call CSNBSAE;

say "-----------------------------------------------------------------";
say "End of Sample";
say "-----------------------------------------------------------------";

exit;

/* --------------------------------------------------------------- */
/* CSNBKGN - Key Generate                                          */
/*                                                                 */
/* Generates either one or two DES or AES keys encrypted under a   */
/* master key (internal form) or KEK (external form).              */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSNBKGN:

KGN_RC = 'FFFFFFFF'x;
KGN_RS = 'FFFFFFFF'x;
KGN_exit_data_length         = '00000000'x;
KGN_exit_data                = '';

ADDRESS linkpgm "CSNBKGN",
   'KGN_RC'                          'KGN_RS'               ,
   'KGN_exit_data_length'            'KGN_exit_data'        ,
   'KGN_key_form'                    'KGN_key_length'       ,
   'KGN_key_type_1'                  'KGN_key_type_2'       ,
   'KGN_kek_identifier_1'            'KGN_kek_identifier_2' ,
   'KGN_generated_key_identifier_1'  'KGN_generated_key_identifier_2';

if (KGN_RC /= '00000000'x) Then
  do;
    say 'KGN Failed   (rc=' c2x(KGN_RC)' rs='c2x(KGN_rs)')' ;
    exit;
  end;

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_count = '00000000'x;
krc2_rule_array = '';

ADDRESS LINKPGM "CSNBKRC2",
                "krc2_rc",
                "krc2_rs",
                "krc2_exit_data_length",
                "krc2_exit_data",
                "krc2_rule_count",
                "krc2_rule_array",
                "krc2_label",
                "krc2_token_length",
                "krc2_token";

if (KRC2_RC /= '00000000'x) Then
  do;
    say 'KRC2 Failed   (rc=' c2x(KRC2_RC)' rs='c2x(KRC2_rs)')' ;
    exit;
  end;

return;

/* --------------------------------------------------------------- */
/* CSNBSAE - Symmetric Algorithm Encipher                          */
/*                                                                 */
/* Encrypts data using a secure, symmetric key                     */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSNBSAE:
sae_rc = 'FFFFFFFF'x;
sae_rs = 'FFFFFFFF'x;
sae_exit_data_length = '00000000'x;
sae_exit_data = '';
sae_key_parms_length = '00000000'x;
sae_key_parms = '';
sae_chain_data_length = '00000020'x;
sae_chain_data = copies('00'x,32);
sae_optional_data_length = '00000000'x;
sae_optional_data = '';

ADDRESS linkpgm "CSNBSAE",
   'SAE_RC'                          'SAE_RS'               ,
   'SAE_exit_data_length'            'SAE_exit_data'        ,
   'SAE_rule_array_count'            'SAE_rule_array'       ,
   'SAE_key_identifier_length'       'SAE_key_identifier'   ,
   'SAE_key_parms_length'            'SAE_key_parms'        ,
   'SAE_block_size'                                         ,
   'SAE_init_vector_length'          'SAE_init_vector'      ,
   'SAE_chain_data_length'           'SAE_chain_data'       ,
   'SAE_clear_text_length'           'SAE_clear_text'       ,
   'SAE_cipher_text_length'          'SAE_cipher_text'      ,
   'SAE_optional_data_length'        'SAE_optional_data';


if (SAE_RC /= '00000000'x) Then
  do;
    say 'SAE (rc=' c2x(SAE_RC)' rs='c2x(SAE_rs)')' ;
    exit;
  end;

return;

/* --------------------------------------------------------------- */
/* CSNBSAD - Symmetric Algorithm Decipher                          */
/*                                                                 */
/* Decrypts data using a secure, symmetric key                     */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSNBSAD:
sad_rc = 'FFFFFFFF'x;
sad_rs = 'FFFFFFFF'x;
sad_exit_data_length = '00000000'x;
sad_exit_data = '';
sad_key_parms_length = '00000000'x;
sad_key_parms = '';
sad_chain_data_length = '00000020'x;
sad_chain_data = copies('00'x,32);
sad_optional_data_length = '00000000'x;
sad_optional_data = '';

ADDRESS linkpgm "CSNBSAD",
   'SAD_RC'                          'SAD_RS'               ,
   'SAD_exit_data_length'            'SAD_exit_data'        ,
   'SAD_rule_array_count'            'SAD_rule_array'       ,
   'SAD_key_identifier_length'       'SAD_key_identifier'   ,
   'SAD_key_parms_length'            'SAD_key_parms'        ,
   'SAD_block_size'                                         ,
   'SAD_init_vector_length'          'SAD_init_vector'      ,
   'SAD_chain_data_length'           'SAD_chain_data'       ,
   'SAD_cipher_text_length'          'SAD_cipher_text'      ,
   'SAD_clear_text_length'           'SAD_clear_text'       ,
   'SAD_optional_data_length'        'SAD_optional_data';


if (SAD_RC /= '00000000'x) Then
  do;
    say 'SAD (rc=' c2x(SAD_RC)' rs='c2x(SAD_rs)')' ;
    exit;
  end;

return;

/* --------------------------------------------------------------- */
/* CSFKDMW - Key Data Set Metadata Write                           */
/*                                                                 */
/* Adds, deletes or modifies metadata of records in an active KDS. */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSFKDMW:
kdmw_rc = 'FFFFFFFF'x;
kdmw_rs = 'FFFFFFFF'x;
kdmw_exit_data_length = '00000000'x;
kdmw_exit_data = '';
kdmw_reserved1_length = '00000000'x;
kdmw_reserved1 = '';
kdmw_reserved2_length = '00000000'x;
kdmw_reserved2 = '';

ADDRESS linkpgm "CSFKDMW",
   'KDMW_rc'                          'KDMW_rs'               ,
   'KDMW_exit_data_length'            'KDMW_exit_data'        ,
   'KDMW_rule_array_count'            'KDMW_rule_array'       ,
   'KDMW_label_count'                 'KDMW_label_list'       ,
   'KDMW_metadata_list_length'        'KDMW_metadata_list'    ,
   'KDMW_results_list'                                        ,
   'KDMW_reserved1_length'            'KDMW_reserved1'        ,
   'KDMW_reserved2_length'            'KDMW_reserved2'        ;

   /* Save the one RC/RS */
   results_list_RC = substr(KDMW_results_list,1,2);

if (KDMW_RC /= '00000000'x | results_list_RC /= '0000'x) Then
  do;
    say 'KDMW Failed';
    say 'KDMW Service (rc=' c2x(KDMW_RC)' rs='c2x(KDMW_rs)')' ;
    say 'KDMW Results (rc=' c2x(results_list_RC)')';
    exit;
  end;

return;

/* --------------------------------------------------------------- */
/* CSFKDMR - Key Data Set Metadata Read                            */
/*                                                                 */
/* Read metadata for records in an active KDS.                     */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSFKDMR:
kdmr_rc = 'FFFFFFFF'x;
kdmr_rs = 'FFFFFFFF'x;
kdmr_exit_data_length = '00000000'x;
kdmr_exit_data = '';
kdmr_reserved1_length = '00000000'x;
kdmr_reserved1 = '';
kdmr_reserved2_length = '00000000'x;
kdmr_reserved2 = '';

ADDRESS linkpgm "CSFKDMR",
   'KDMR_rc'                          'KDMR_rs'               ,
   'KDMR_exit_data_length'            'KDMR_exit_data'        ,
   'KDMR_rule_array_count'            'KDMR_rule_array'       ,
   'KDMR_record_label'                                        ,
   'KDMR_metadata_list_length'        'KDMR_metadata_list'    ,
   'KDMR_output_list_length'          'KDMR_output_list'      ,
   'KDMR_reserved1_length'            'KDMR_reserved1'        ,
   'KDMR_reserved2_length'            'KDMR_reserved2'        ;

if (KDMR_RC /= '00000000'x) Then
  do;
    say 'KDMR Failed   (rc=' c2x(KDMR_RC)' rs='c2x(KDMR_rs)')' ;
    exit;
  end;

return;

/* --------------------------------------------------------------- */
/* CSNBKRD - Key Record Delete                                     */
/*                                                                 */
/* Deletes a key record from the CKDS.                             */
/*                                                                 */
/* See the ICSF Application Programmer's Guide for more details.   */
/* --------------------------------------------------------------- */
CSNBKRD:
krd_rc = 'FFFFFFFF'x;
krd_rs = 'FFFFFFFF'x;
krd_exit_data_length = '00000000'x;
krd_exit_data = '';
krd_rule_array_count = '00000001'x;
krd_rule_array = 'LABEL-DL';

ADDRESS LINKPGM "CSNBKRD",
                "krd_rc",
                "krd_rs",
                "krd_exit_data_length",
                "krd_exit_data",
                "krd_rule_array_count",
                "krd_rule_array",
                "krd_label";

if (KRD_RC /= '00000000'x & KRD_RS /= '0000271C'x) Then
  say 'KRD Failed   (rc=' c2x(KRD_RC)' rs='c2x(KRD_rs)')' ;

return;

/* --------------------------------------------------------------- */
/* Debug ;-)                                                       */
/* --------------------------------------------------------------- */
NOVALUE:
Say "Condition NOVALUE was raised."
Say CONDITION("D") "variable was not initialized."
Say SOURCELINE(sigl)
Exit

0 comments
15 views

Permalink