See Code disclaimer information for information pertaining to code examples.
Refer to Scenario: Key Management and File Encryption Using the Cryptographic Services APIs for a description of this scenario.
/*-------------------------------------------------------------------*/ /* */ /* Sample C program: Write_Cus */ /* */ /* COPYRIGHT 5722-SS1 (c) IBM Corp 2004 */ /* */ /* This material contains programming source code for your */ /* consideration. These examples have not been thoroughly */ /* tested under all conditions. IBM, therefore, cannot */ /* guarantee or imply reliability, serviceability, or function */ /* of these programs. All programs contained herein are */ /* provided to you "AS IS". THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* EXPRESSLY DISCLAIMED. IBM provides no program services for */ /* these programs and files. */ /* */ /* Description: */ /* This is a sample program to demonstrate use of the Cryptographic */ /* Services APIs. APIs demonstrated in this program are: */ /* Create Algorithm Context */ /* Create Key Context */ /* Generate Pseudorandom Numbers */ /* Encrypt Data */ /* Destroy Key Context */ /* Destroy Algorithm Context */ /* */ /* Function: */ /* Get customer information, encrypt it, and write it to the */ /* Customer Data file (CUSDTA). The file key is kept in the */ /* Customer Processing Information file (CUSPI). */ /* */ /* Refer to the iSeries (TM) Information Center for a full */ /* description of this scenario. */ /* */ /* Use the following commands to compile this program: */ /* CRTCMOD MODULE(MY_LIB/WRITE_CUS) SRCFILE(MY_LIB/MY_SRC) */ /* CRTSRVPGM SRVPGM(MY_LIB/WRITE_CUS) + */ /* MODULE(MY_LIB/WRITE_CUS MY_LIB/GET_CUSTOMER_INFO) + */ /* BNDSRVPGM(QC3CTX QC3PRNG QC3DTAEN) */ /* */ /*-------------------------------------------------------------------*/ /*-------------------------------------------------------------------*/ /* Retrieve various structures/utilities. */ /*-------------------------------------------------------------------*/ #include <stdio.h> /* Standard I/O header */ #include <stdlib.h> /* General utilities */ #include <stddef.h> /* Standard definitions */ #include <string.h> /* String handling utilities */ #include <recio.h> /* Record I/O routines */ #include <qusec.h> /* Error code structure */ #include <qc3ctx.h> /* Hdr file for Context APIs */ #include <qc3prng.h> /* Hdr file for PRNG APIs */ #include <qc3dtaen.h> /* Hdr file for Encrypt Dta API*/ /*-------------------------------------------------------------------*/ /* The following structures were generated with GENCSRC. */ /*-------------------------------------------------------------------*/ #ifdef __cplusplus #include <bcd.>> #else #include <decimal.h> #endif /* ------------------------------------------------------- * // PHYSICAL FILE : MY_LIB/CUSPI // FILE LAST CHANGE DATE : 2004/02/11 // RECORD FORMAT : CUSPIREC // FORMAT LEVEL IDENTIFIER : 248C15A88E09C * ------------------------------------------------------- */ typedef _Packed struct { char KEY[16]; /* ENCRYPTION KEY */ #ifndef __cplusplus decimal( 8, 0) LASTCUS; #else _DecimalT< 8, 0> LASTCUS; /* LAST CUSTOMER NUMBER */ /* BCD class SPECIFIED IN DDS */ #endif } CUSPIREC_both_t; /* ------------------------------------------------------- * // PHYSICAL FILE : MY_LIB/CUSDTA // FILE LAST CHANGE DATE : 2004/02/11 // RECORD FORMAT : CUSDTAREC // FORMAT LEVEL IDENTIFIER : 434C857F6F5B3 * ------------------------------------------------------- */ typedef _Packed struct { #ifndef __cplusplus decimal( 8, 0) CUSNUM; #else _DecimalT< 8, 0> CUSNUM; /* CUSTOMER NUMBER */ /* BCD class SPECIFIED IN DDS */ #endif char IV[16]; /* INITIALIZATION VECTOR */ #ifndef __cplusplus decimal(10, 2) ARBAL; #else _DecimalT<10, 2> ARBAL; /* ACCOUNTS RECEIVABLE BALANCE */ /* BCD class SPECIFIED IN DDS */ #endif char ECUSDTA[80]; /* ENCRYPTED CUSTOMER DATA */ } CUSDTAREC_both_t; /*-------------------------------------------------------------------*/ /* Function declarations */ /*-------------------------------------------------------------------*/ /* Get a customer information */ void Get_Customer_Info(char *customerInfo, decimal(8, 0) *customerNumber); /*-------------------------------------------------------------------*/ /* Start of mainline code. */ /*-------------------------------------------------------------------*/ int Write_Cus() { /*-------------------------------------------------------------------*/ /* Return codes */ /*-------------------------------------------------------------------*/ int rtn; /* Return code */ #define ERROR -1 #define OK 0 /*-------------------------------------------------------------------*/ /* File handling variables */ /*-------------------------------------------------------------------*/ _RFILE *cuspiPtr; /* Pointer to CUSPI file */ _RFILE *cusdtaPtr; /* Pointer to CUSDTA file */ CUSPIREC_both_t cuspi; /* CUSPI record */ CUSDTAREC_both_t cusdtain; /* CUSDTA input record */ CUSDTAREC_both_t cusdtaout; /* CUSDTA output record */ /*-------------------------------------------------------------------*/ /* Parameters needed by the Cryptographic Services APIs */ /*-------------------------------------------------------------------*/ Qus_EC_t errCode; /* Error code structure */ char csp; /* Crypto service provider */ Qc3_Format_ALGD0200_T algD; /* Block cipher alg description*/ char AESctx[8]; /* AES alg context token */ int keySize; /* Key size */ char keyFormat; /* Key format */ int keyType; /* Key type */ char keyForm; /* Key form */ int keyStringLen; /* Length of key string */ Qc3_Format_KEYD0400_T kskey; /* Key store key name structure*/ char KEKctx[8]; /* KEK key context token */ char FKctx[8]; /* File key context token */ char pcusdta[80]; /* Plaintext customer data */ int cipherLen; /* Length of ciphertext */ int plainLen; /* Length of plaintext */ int rtnLen; /* Return length */ char PRNtype; /* PRN type */ char PRNparity; /* PRN parity */ unsigned int PRNlen; /* Length of PRN data */ /*-------------------------------------------------------------------*/ /* Input values from Get Customer Information. */ /*-------------------------------------------------------------------*/ char inCusInfo[80];/* Customer Information */ decimal(8, 0) inCusNum; /* Customer number */ /*-------------------------------------------------------------------*/ /* Initializations */ /*-------------------------------------------------------------------*/ /* Init to good return */ rtn = OK; /* Set to generate exceptions */ memset(&errCode, 0, sizeof(errCode)); /* Use any crypto provider */ csp = Qc3_Any_CSP; /* Set inCusInfo to null */ memset(inCusInfo, 0, sizeof(inCusInfo)); /*-------------------------------------------------------------------*/ /* Create an AES algorithm context for the key-encrypting key (KEK). */ /*-------------------------------------------------------------------*/ memset(&algD, 0, sizeof(algD)); /* Init alg description to null*/ algD.Block_Cipher_Alg = Qc3_AES; /* Set AES algorithm */ algD.Block_Length = 16; /* Block size is 16 */ algD.Mode = Qc3_CBC; /* Use cipher block chaining */ algD.Pad_Option = Qc3_No_Pad; /* Do not pad */ /* Create algorithm context */ Qc3CreateAlgorithmContext((unsigned char *)&algD, Qc3_Alg_Block_Cipher, AESctx, &errCode); /*-------------------------------------------------------------------*/ /* Create a key context for the key-encrypting key (KEK). */ /*-------------------------------------------------------------------*/ keyFormat = Qc3_KSLabel_Struct; /* Key format is keystore label*/ keyStringLen = sizeof(kskey); /* Length of key string */ keyType = Qc3_AES; /* Key type is AES */ keyForm = Qc3_Clear; /* Key string is clear */ memset(&kskey, 0, sizeof(kskey)); /* Init name structure to null */ /* Set key store file name */ memset(kskey.Key_Store, 0x40, sizeof(kskey.Key_Store)); memcpy(kskey.Key_Store,"CUSKEYFILEMY_LIB", 16); /* Set key store label */ memset(kskey.Record_Label, 0x40, sizeof(kskey.Record_Label)); memcpy(kskey.Record_Label, "CUSDTAKEK", 9); /* Create key context */ Qc3CreateKeyContext((char*)&kskey, &keyStringLen, &keyFormat, &keyType, &keyForm, NULL, NULL, KEKctx, &errCode); /*-------------------------------------------------------------------*/ /* Open Customer Processing Information file. Read first record */ /* to obtain the encrypted file key and last customer number. */ /*-------------------------------------------------------------------*/ /* Open CUSPI file */ if ((cuspiPtr = _Ropen("MY_LIB/CUSPI", "rr+, arrseq=Y, riofb=N")) == NULL) { /* If null ptr returned */ /* Send error message */ printf("Open of Customer Processing Information file (CUSPI) failed."); return ERROR; /* Return with error */ } /* Read the first(only) record */ /* to get encrypted file key. */ if ((_Rreadf(cuspiPtr, &cuspi, sizeof(cuspi), __DFT))->num_bytes == EOF) { /* If record not found */ /* Send error message */ printf("Customer Processing Information (CUSPI) record missing."); _Rclose(cuspiPtr); /* Close CUSPI file */ return ERROR; /* Return with error */ } /*-------------------------------------------------------------------*/ /* Create a key context for the file key. */ /*-------------------------------------------------------------------*/ keySize = sizeof(cuspi.KEY); /* Set key size */ keyFormat = Qc3_Bin_String; /* Key is a binary string */ keyType = Qc3_AES; /* Key type is AES */ keyForm = Qc3_Encrypted; /* Key is encrypted with a KEK */ /* Create key context */ Qc3CreateKeyContext(cuspi.KEY, &keySize, &keyFormat, &keyType, &keyForm, KEKctx, AESctx, FKctx, &errCode); /*-------------------------------------------------------------------*/ /* Wipe out the encrypted file key value from program storage. */ /*-------------------------------------------------------------------*/ /* Wipe out encrypted file key */ memset(cuspi.KEY, 0, sizeof(cuspi.KEY)); /*-------------------------------------------------------------------*/ /* Open Customer Data file. */ /*-------------------------------------------------------------------*/ /* Open CUSDTA file */ if ((cusdtaPtr = _Ropen("MY_LIB/CUSDTA", "rr+, riofb=N")) == NULL) { /* If null ptr returned */ /* Send error message */ printf("Open of CUSDTA file failed."); _Rclose(cuspiPtr); /* Close CUSPI file */ return ERROR; /* Return with error */ } /*-------------------------------------------------------------------*/ /* Get customer information. */ /*-------------------------------------------------------------------*/ /* Get customer information */ /* and customer number */ Get_Customer_Info(inCusInfo, &inCusNum); /*-------------------------------------------------------------------*/ /* Repeat loop until no more customers to add/update. */ /*-------------------------------------------------------------------*/ /* Exit program when customer */ while (inCusNum != 99999999) /* number = 99999999 */ { /*-------------------------------------------------------------------*/ /* Generate an Initialization Vector for the customer. */ /*-------------------------------------------------------------------*/ PRNtype = Qc3PRN_TYPE_NORMAL; /* Generate real random numbers*/ PRNparity = Qc3PRN_NO_PARITY; /* Do not adjust parity */ PRNlen = 16; /* Generate 16 bytes */ Qc3GenPRNs(cusdtaout.IV, PRNlen, PRNtype, PRNparity, &errCode); /*-------------------------------------------------------------------*/ /* Encrypt customer information. */ /*-------------------------------------------------------------------*/ /* Copy IV to alg description */ memcpy(algD.Init_Vector, cusdtaout.IV, 16); /* Encrypt customer data */ plainLen = sizeof(inCusInfo); cipherLen = sizeof(cusdtaout.ECUSDTA); Qc3EncryptData(inCusInfo, &plainLen, Qc3_Data, (char*)&algD, Qc3_Alg_Block_Cipher, FKctx, Qc3_Key_Token, &csp, NULL, cusdtaout.ECUSDTA, &cipherLen, &rtnLen, &errCode); /*-------------------------------------------------------------------*/ /* Write customer data to file CUSDTA. */ /*-------------------------------------------------------------------*/ if (inCusNum == 0) /* If new customer */ { cuspi.LASTCUS += 1; /* Increment last customer num */ cusdtaout.CUSNUM=cuspi.LASTCUS; /* Give new customer a number */ cusdtaout.ARBAL = 10; /* Set balance to setup fee */ /* Write record to file */ if ((_Rwrite(cusdtaPtr, &cusdtaout, sizeof(cusdtaout)))->num_bytes < sizeof(cusdtaout)) { /* If write fails */ /* Send error message */ printf("Error occurred writing record to CUSDTA file."); inCusNum = 99999999; /* Set to exit loop */ rtn = ERROR; /* Indicate error condition */ } } else /* If existing customer */ { /* Read existing record */ if ((_Rreadk(cusdtaPtr, &cusdtain, sizeof(cusdtain), __KEY_EQ, &inCusNum, sizeof(inCusNum))) -> num_bytes < sizeof(cusdtain)) { /* If read fails */ /* Send error message */ printf("Error occurred reading record in CUSDTA file."); inCusNum = 99999999; /* Set to exit loop */ rtn = ERROR; /* Indicate error condition */ } /* Copy customer number */ cusdtaout.CUSNUM = cusdtain.CUSNUM; /* Copy balance */ cusdtaout.ARBAL = cusdtain.ARBAL; /* Update customer record */ if ((_Rupdate(cusdtaPtr, &cusdtaout, sizeof(cusdtaout)))->num_bytes < sizeof(cusdtaout)) { /* If update fails */ /* Send error message */ printf("Error occurred updating record in CUSDTA file."); inCusNum = 99999999; /* Set to exit loop */ rtn = ERROR; /* Indicate error condition */ } } /*-------------------------------------------------------------------*/ /* Get customer information. */ /*-------------------------------------------------------------------*/ /* Get customer information */ if (rtn == OK) /* and customer number */ Get_Customer_Info(inCusInfo, &inCusNum); } /* Return to top of while loop */ /*-------------------------------------------------------------------*/ /* Update last customer number in CUSPI file. */ /*-------------------------------------------------------------------*/ /* Write record to file */ if ((_Rwrite(cuspiPtr, &cuspi, sizeof(cuspi)))->num_bytes < sizeof(cuspi)) { /* If write fails */ /* Send error message */ printf("Error occurred updating record in CUSPI file."); } /*-------------------------------------------------------------------*/ /* Cleanup. */ /*-------------------------------------------------------------------*/ /* Clear plaintext data */ memset(inCusInfo, 0, sizeof(inCusInfo)); /* Destroy file key context */ Qc3DestroyKeyContext(FKctx, &errCode); /* Destroy KEK context */ Qc3DestroyKeyContext(KEKctx, &errCode); /* Destroy the alg context */ Qc3DestroyAlgorithmContext(AESctx, &errCode); /* Close CUSDTA file */ _Rclose(cusdtaPtr); /* Close CUSPI file */ _Rclose(cuspiPtr); /* Return */ return rtn; }
Top | Cryptographic Services APIs |APIs by category |