IBM Crypto Education Community - Group home

Rexx Sample: Use Format Preserving Encryption with protected key

  

/* Rexx */

/* Sample: Perform Field Level Encipher / Decipher (FLE/FLD)         */
/*         using protected key                                       */
/*-------------------------------------------------------------------*/
/* Description:                                                      */
/*                                                                   */
/* To use protected key tokens in FLE/FLD the security administrator */
/* must issue these commands:                                        */
/*                                                                   */
/* Note: CSFKEYS SAF checking must be active                         */
/* . RDEFINE CSFKEYS CSF-PROTECTED-KEY-TOKEN ICSF(SYMCPACFWRAP(YES)) */
/*     UACC(NONE)                                                    */
/* . PERMIT CSF-PROTECTED-KEY-TOKEN ID(userid) CLASS(CSFKEYS)        */
/*     ACCESS(READ)                                                  */
/* . SETROPTS RACLIST(CSFKEYS) REFRESH                               */
/*                                                                   */
/* This REXX sample will                                             */
/* - Generate a 256-bit AES DATA key                                 */
/* - Use the AES DATA key in FLE to encrypt data                     */
/* - Use the AES DATA key in FLD to decrypt data                     */
/*                                                                   */
/* See the ICSF Application Programmer's Guide for more details on   */
/* the callable services used in this sample.                        */

/*                                                                   */

/* NOTE:                                                             */

/* - ICSF HCR77B1 with PTF OA51102 is required to use encrypted key  */

/*   tokens in FLE/FLD (keys that do not reside in the CKDS).        */

/*   Prior to HCR77B1, FLE/FLD only supported encrypted key labels.  */

/*-------------------------------------------------------------------*/
signal on novalue;

/*-------------------------------------------------------------------*/
/* Key Generate                                                      */
/* - generate a 256-bit AES DATA key                                 */
/*                                                                   */
/* See the ICSF Application Programmer's Guide for more details.     */
/*-------------------------------------------------------------------*/
KGN_key_form   = 'OP  ' ;
KGN_key_length = 'KEYLN32 ' ; /* 256-bit */
KGN_key_type_1 = 'AESDATA ' ;
call KGN ;

say 'KGN generated key:' ;
say c2x(substr(KGN_generated_key_identifier_1, 1, 32)) ;
say c2x(substr(KGN_generated_key_identifier_1, 33, 32)) ;

/*-------------------------------------------------------------------*/
/* Field Level Encipher                                              */
/* - use generated AESDATA key to encrypt data                       */
/*-------------------------------------------------------------------*/
FLE_key_identifier_length = '00000040'x ;
FLE_key_identifier        = KGN_generated_key_identifier_1 ;
FLE_source_text_length    = '00000013'x ;
FLE_source_text           = 'abcXYZ7#$@%!0678123' ;
FLE_target_text_length    = '00000013'x ;
FLE_target_text           = '0000000000000000000' ;

call FLE ;

say 'FLE encrypted text length:' c2x(FLE_target_text_length) ;
say 'FLE encrypted text:' c2x(FLE_target_text) ;

/*-------------------------------------------------------------------*/
/* Field Level Decipher                                              */
/* - decrypt the encrypted data from FLE                             */
/*-------------------------------------------------------------------*/
FLD_key_identifier_length = FLE_key_identifier_length ;
FLD_key_identifier        = FLE_key_identifier ;
call FLD ;

say 'FLD target text length:' c2x(FLD_target_text_length) ;
say 'FLD target text:' FLD_target_text ;

/* the decrypted text should match the clear source text from FLE */
IF FLD_target_text = FLE_source_text THEN
  say 'decrypted text matches!!' ;

EXIT ;

/*-------------------------------------------------------------------*/
/* Key Generate                                                      */
/*-------------------------------------------------------------------*/
KGN:

/* initialize parameter list */
KGN_rc         = 'FFFFFFFF'x ;
KGN_rs         = 'FFFFFFFF'x ;
KGN_exit_data_length = '00000000'x ;
KGN_exit_data  = '' ;
KGN_key_type_2 = '' ;
KGN_KEK_key_identifier_1 = '' ;
KGN_KEK_key_identifier_2 = '' ;
KGN_generated_key_identifier_1 = copies('00'x,64) ;
KGN_generated_key_identifier_2 = copies('00'x,64) ;

/* call CSNBKGN */
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_key_identifier_1'       'KGN_KEK_key_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 ;
/*-------------------------------------------------------------------*/
/* Field Level Encipher                                              */
/*-------------------------------------------------------------------*/
FLE:

/* initialize parameter list */
FLE_rc                     = 'FFFFFFFF'x ;
FLE_rs                     = 'FFFFFFFF'x ;
FLE_exit_data_length       = '00000000'x ;
FLE_exit_data              = '' ;
FLE_rule_array_count       = '00000005'x ;
FLE_rule_array             = 'AESVFPE ' ||,
                             'KEYIDENT' ||,
                             'TWEAK   ' ||,
                             'KEY     ' ||,
                             'EPRINT  ' ;
FLE_key_derive_data_length = '00000000'x ;
FLE_key_derive_data        = '' ;
FLE_context_data_length    = '00000010'x ;
FLE_context_data           = '01FFFFFFFFFFFFFF01FFFFFFFFFFFFFF'x
FLE_charset_parms_length   = '00000000'x ;
FLE_charset_parms          = '' ;
FLE_reserved_length        = '00000000'x ;
FLE_reserved               = '' ;
FLE_source_text_id         = '00000000'x ;
FLE_target_text_id         = '00000000'x ;

/* call CSNBFLE */
address linkpgm 'CSNBFLE' ,
 'FLE_rc'                     'FLE_rs' ,
 'FLE_exit_data_length'       'FLE_exit_data' ,
 'FLE_rule_array_count'       'FLE_rule_array' ,
 'FLE_key_identifier_length'  'FLE_key_identifier' ,
 'FLE_key_derive_data_length' 'FLE_key_derive_data' ,
 'FLE_context_data_length'    'FLE_context_data' ,
 'FLE_charset_parms_length'   'FLE_charset_parms' ,
 'FLE_reserved_length'        'FLE_reserved' ,
 'FLE_source_text_id' ,
 'FLE_source_text_length'     'FLE_source_text' ,
 'FLE_target_text_id' ,
 'FLE_target_text_length'     'FLE_target_text' ;

IF (FLE_rc /= '00000000'x) THEN
 DO ;
  say 'FLE failed: rc =' c2x(FLE_rc) 'rs =' c2x(FLE_rs) ;
  EXIT ;
 END ;

return ;

/*-------------------------------------------------------------------*/
/* Field Level Decipher                                              */
/* - decrypt the encrypted data from FLE                             */
/*                                                                   */
/* See the ICSF Application Programmer's Guide for more details.     */
/*-------------------------------------------------------------------*/
FLD:

/* initialize parameter list */
FLD_rc                     = 'FFFFFFFF'x ;
FLD_rs                     = 'FFFFFFFF'x ;
FLD_exit_data_length       = '00000000'x ;
FLD_exit_data              = '' ;
FLD_rule_array_count       = FLE_rule_array_count ;
FLD_rule_array             = FLE_rule_array ;
FLD_key_derive_data_length = FLE_key_derive_data_length ;
FLD_key_derive_data        = FLE_key_derive_data ;
FLD_context_data_length    = FLE_context_data_length ;
FLD_context_data           = FLE_context_data ;
FLD_charset_parms_length   = FLE_charset_parms_length ;
FLD_charset_parms          = FLE_charset_parms ;
FLD_reserved_length        = '00000000'x ;
FLD_reserved               = '' ;
FLD_source_text_id         = '00000000'x ;
FLD_source_text_length     = FLE_target_text_length ;
FLD_source_text            = FLE_target_text ;
FLD_target_text_id         = '00000000'x ;
FLD_target_text_length     = FLE_target_text_length ;
FLD_target_text            = d2c(0,c2d(FLD_target_text_length)) ;

/* call CSNBFLD */
address linkpgm 'CSNBFLD' ,
 'FLD_rc'                     'FLD_rs' ,
 'FLD_exit_data_length'       'FLD_exit_data' ,
 'FLD_rule_array_count'       'FLD_rule_array' ,
 'FLD_key_identifier_length'  'FLD_key_identifier' ,
 'FLD_key_derive_data_length' 'FLD_key_derive_data' ,
 'FLD_context_data_length'    'FLD_context_data' ,
 'FLD_charset_parms_length'   'FLD_charset_parms' ,
 'FLD_reserved_length'        'FLD_reserved' ,
 'FLD_source_text_id' ,
 'FLD_source_text_length'     'FLD_source_text' ,
 'FLD_target_text_id' ,
 'FLD_target_text_length'     'FLD_target_text' ;

IF (FLD_rc /= '00000000'x) THEN
 DO ;
  say 'FLD failed: rc =' c2x(FLD_rc) 'rs =' c2x(FLD_rs) ;
  EXIT ;
 END ;

return ;