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