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 |