/* REXX */ /* Pervasive (Data Set) Encryption: Step 6 of 10 */ /*-------------------------------------------------------------------*/ /* Generate a secure AES CIPHER key, store the key in the CKDS and */ /* display the key label and key. If the key label already exists, */ /* return the existing key label. */ /*-------------------------------------------------------------------*/ /* Instructions: */ /* - Update aes_key_label with your desired key label name */ /* */ /* Note: An example key label naming scheme is */ /* DATASET..ENCRKEY. */ /* */ /* - EXECUTE THIS CLIST FROM TSO */ /* (E.G. EX 'HLQ.MLD.LLQ(GENKEYC)') */ /*-------------------------------------------------------------------*/ SIGNAL ON NOVALUE; aes_key_label = , LEFT('keylabel.to.be.created',64); /*-------------------------------------------------------------------*/ /* Check if the key exists in the CKDS (to prevent overwriting) */ /*-------------------------------------------------------------------*/ KRR2_rc = 'FFFFFFFF'X; KRR2_label = aes_key_label; KRR2_token = COPIES('00'X,725); CALL CSNBKRR2; /* If key is found, print and exit */ IF (KRR2_rc = '00000000'X) THEN DO; SAY 'Secure key label: '||STRIP(aes_key_label); SAY ' already exists. Stopping.'; EXIT; END; /*-------------------------------------------------------------------*/ /* Build a skeleton with the correct key usage and key management */ /*-------------------------------------------------------------------*/ KTB2_rule_array_count = '0000000C'X; KTB2_rule_array =, 'INTERNALAES CIPHER XPRTCPACANY-MODE'||, 'NOEX-SYMNOEX-RAWNOEXUASYNOEXAASYNOEX-DESNOEX-AESNOEX-RSA'; KTB2_target_key_token_length = '000002D5'X; KTB2_target_key_token = COPIES('DD'X,725); CALL CSNBKTB2; SAY 'Skeleton token created.'; /*-------------------------------------------------------------------*/ /* 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 = '000002D5'x; KGN2_generated_key_id_1 = LEFT(KTB2_target_key_token,725); KGN2_generated_key_id_2_length = '00000000'x; KGN2_generated_key_id_2 = ''; Call CSNBKGN2; SAY 'Random secure key token generated.'; /*-------------------------------------------------------------------*/ /* Store the key in the CKDS */ /*-------------------------------------------------------------------*/ KRC2_label = aes_key_label; KRC2_token_length = KGN2_generated_key_id_1_length; KRC2_token = KGN2_generated_key_id_1; CALL CSNBKRC2; SAY 'Successfully written to the CKDS.'; /*-------------------------------------------------------------------*/ /* Read the key from the CKDS */ /*-------------------------------------------------------------------*/ KRR2_label = aes_key_label; KRR2_token = COPIES('00'X,725); CALL CSNBKRR2; IF (KRR2_rc \= '00000000'X) THEN DO; SAY 'KRR2 Failed (rc=' C2X(KRR2_rc)' rs='C2X(KRR2_rs)')' ; SAY 'Secure key label: '||STRIP(aes_key_label); SAY ' was not successfully created'; EXIT; END; KRR2_token = LEFT(KRR2_token,C2D(KRR2_token_len)); IF (KRR2_token \= KGN2_generated_key_id_1) THEN DO; SAY 'Secure key label: '||STRIP(aes_key_label); SAY ' returned from KRR does not match!'; EXIT; END; SAY 'Secure key label: '||STRIP(aes_key_label); SAY ' was successfully created'; SAY "-----------------------------------------------------------------" SAY "End of Sample" SAY "-----------------------------------------------------------------" EXIT; /* --------------------------------------------------------------- */ /* CSNBKRR2 - Key Record Read (CKDS) */ /* */ /* Reads a 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_rule_count = '00000000'X; KRR2_rule_array = ''; KRR2_token_len = D2C(725,4); KRR2_token = COPIES('00'X,725); ADDRESS LINKPGM "CSNBKRR2", "KRR2_rc", "KRR2_rs", "KRR2_exit_data_length", "KRR2_exit_data", "KRR2_rule_count", "KRR2_rule_array", "KRR2_label", "KRR2_token_len", "KRR2_token"; RETURN; /* --------------------------------------------------------------- */ /* CSNBKTB2 - Key Token Build2 */ /* */ /* Builds a variable-length AES skeleton token. */ /* */ /* See the ICSF Application Programmer's Guide for more details. */ /* --------------------------------------------------------------- */ CSNBKTB2: KTB2_return_code = 'FFFFFFFF'X; KTB2_reason_code = 'FFFFFFFF'X; KTB2_exit_data_length = '00000000'X; KTB2_exit_data = ''; KTB2_clear_key_bit_length = '00000000'X; KTB2_clear_key_value = '00000000'X; KTB2_key_name_length = '00000000'X; KTB2_key_name = ''; KTB2_user_associated_data_length = '00000000'X; KTB2_user_associated_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('DD'X,725); ADDRESS LINKPGM "CSNBKTB2" , "KTB2_return_code" , "KTB2_reason_code" , "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_associated_data_length" , "KTB2_user_associated_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_return_code /= '00000000'x) THEN DO; SAY 'KTB2: RC='||C2X(KTB2_return_code)||, ' RS='||C2X(KTB2_reason_code); EXIT; END; RETURN; /* --------------------------------------------------------------- */ /* 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. */ /* --------------------------------------------------------------- */ 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 = , LEFT(KGN2_generated_key_id_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_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; /* --------------------------------------------------------------- */ /* Debug */ /* --------------------------------------------------------------- */ NOVALUE: SAY 'Condition NOVALUE was raised.'; SAY CONDITION('D')||' variable was not initialized.'; SAY SOURCELINE(sigl) EXIT;