Example: Creating a PKA key with your Cryptographic Coprocessor

Change this IBM i program example to suit your needs for creating a PKA key with your Cryptographic Coprocessor.

Note: Read the Code license and disclaimer information for important legal information.

If you choose to use this program example, change it to suit your specific needs. For security reasons, IBM recommends that you individualize these program examples rather than using the default values provided.

/*---------------------------------------------------------------*/
/* Generate PKA keys in keystore.                               */
/*                                                               */
/*  COPYRIGHT      5769-SS1 (c) IBM Corp 1999, 2007              */
/*                                                               */
/*  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.                                    */
/*                                                               */
/* Parameters:                                                   */
/*  char * key label,  1 to 64 characters                        */
/*                                                               */
/* Examples:                                                     */
/*   CALL PGM(PKAKEYGEN) PARM('TEST.LABEL.1')                    */
/*                                                               */
/* Note: This program assumes the card you want to load is       */
/*       already identifed either by defaulting to the CRP01     */
/*       device or has been explicitly named using the           */
/*       Cryptographic_Resource_Allocate verb. Also this         */
/*       device must be varied on and you must be authorized     */
/*       to use this device descrption.                          */
/*                                                               */
/*       This program also assumes the keystore file you will   */
/*       use is already identifed either by being specified on   */
/*       the cryptographic device or has been explicitly named   */
/*       using the Key_Store_Designate verb. Also you must be    */
/*       authorized to add and update records in this file.      */
/*                                                               */
/* Use the following commands to compile this program:           */
/* ADDLIBLE LIB(QCCA)                                            */
/* CRTCMOD MODULE(PKAKEYGEN) SRCFILE(SAMPLE)                     */
/* CRTPGM  PGM(PKAKEYGEN) MODULE(PKAKEYGEN)  +                   */
/*         BNDSRVPGM(QCCA/CSNDKRC QCCA/CSNDPKG)                  */
/*                                                               */
/* Note: authority to the CSNDKRC and CSNDPKG service programs   */
/*       in the QCCA library is assumed.                         */
/*                                                               */
/* Common Cryptographic Architecture (CCA) verbs used:           */
/*   PKA_Key_Record_Create (CSNDKRC)                             */
/*   PKA_Key_Generate (CSNDPKG)                                  */
/*                                                               */
/*---------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "csucincl.h"            /* header file for CCA Cryptographic
                                    Service Provider                 */

int main(int argc, char *argv[])
 {

/*-------------------------------------------------------------------*/
/* standard return codes                                             */
/*-------------------------------------------------------------------*/

#define ERROR -1
#define OK     0

/*-------------------------------------------------------------------*/
/* standard CCA parameters                                           */
/*-------------------------------------------------------------------*/

  long return_code;
  long reason_code;
  long exit_data_length;
  char exit_data[2];
  char rule_array[4][8];
  long rule_array_count;

/*-------------------------------------------------------------------*/
/* fields unique to this sample program                              */
/*-------------------------------------------------------------------*/

  char key_label[64];            /* identify record in keystore to
				    hold generated key								               */
  #pragma pack (1)

  typedef struct rsa_key_token_header_section {
      char token_identifier;
      char version;
      short key_token_struct_length;
      char reserved_1[4];
  } rsa_key_token_header_section;

  typedef struct rsa_private_key_1024_bit_section {
      char  section_identifier;
      char  version;
      short section_length;
      char  hash_of_private_key[20];
      short reserved_1;
      short master_key_verification_pattern;
      char  key_format_and_security;
      char  reserved_2;
      char  hash_of_key_name[20];
      char  key_usage_flag;
      char  rest_of_private_key[312];
  } rsa_private_key_1024_bit_section;

  typedef struct rsa_public_key_section {
      char  section_identifer;
      char  version;
      short section_length;
      short reserved_1;
      short exponent_field_length;
      short modulus_length;
      short modulus_length_in_bytes;
      char  exponent;
  } rsa_public_key_section;    
        
  struct {
      rsa_key_token_header_section      rsa_header;
      rsa_private_key_1024_bit_section  rsa_private_key;
      rsa_public_key_section            rsa_public_key;
  } key_token;


  struct {
      short modlen;
      short modlenfld;
      short pubexplen;
      short prvexplen;
      long  pubexp;
  } prvPubl;

#pragma pack ()

  long key_struct_length;
  long zero = 0;
  long key_token_length;
  
  long regen_data_length;
  long generated_key_id_length;
  
/*-------------------------------------------------------------------*/
/* Create record in keystore                                        */
/*-------------------------------------------------------------------*/
  rule_array_count = 0;
  key_token_length = 0;
  memset(key_label, ' ', 64);
  memcpy(key_label, argv[1], strlen(argv[1]));

  CSNDKRC(&return_code,
	  &reason_code,
	  &exit_data_length,
	  exit_data,
	  &rule_array_count,
	  "\0",                 /* rule_array                       */
	  key_label,
	  &key_token_length,
	  "\0");                /* key token                        */

  if (return_code != 0)
  {
      printf("Record could not be added to keystore for reason %d/%d\n\n",
	     return_code, reason_code);
      return ERROR;
  }
  else
  {
      printf("Record added to keystore\n");
      printf("SAPI returned %ld/%ld\n", return_code, reason_code);
  }

/*-------------------------------------------------------------------*/
/* Build a key token, needed to generate PKA key                     */
/*-------------------------------------------------------------------*/
  memset(&key_token, 0X00, sizeof(key_token));

  key_token.rsa_header.token_identifier = 0X1E; /* external token   */
  key_token.rsa_header.key_token_struct_length = sizeof(key_token);

  key_token.rsa_private_key.section_identifier =
      0X02;                                     /* RSA private key  */
  key_token.rsa_private_key.section_length =
         sizeof(rsa_private_key_1024_bit_section);
  key_token.rsa_private_key.key_usage_flag = 0X80;

  key_token.rsa_public_key.section_identifer = 0X04; /* RSA public key   */
  key_token.rsa_public_key.section_length =
      sizeof(rsa_public_key_section);
  key_token.rsa_public_key.exponent_field_length = 1;
  key_token.rsa_public_key.modulus_length = 512;
  key_token.rsa_public_key.exponent = 0x03;

  key_token_length = sizeof(key_token);

  printf("Key token built\n");
  
/*-------------------------------------------------------------------*/
/* Generate a key                                                    */
/*-------------------------------------------------------------------*/

  rule_array_count = 1;
  regen_data_length = 0;
 /*  key_token_length = 64; */
  generated_key_id_length = 2500;

  CSNDPKG(&return_code,
	  &reason_code,
	  &exit_data_length,
	  exit_data,
	  &rule_array_count,
	  "MASTER  ",            /* rule_array                      */
	  &regen_data_length,
	  "\0",                  /* regeneration_data, none needed  */
	  &key_token_length,     /* skeleton_key_token_length       */
	  (char *)&key_token,    /* skeleton_key_token built above  */
	  "\0",                  /* transport_id, only needed for
				    						XPORT keys                      */
	  &generated_key_id_length,
	  key_label);            /* generated_key_id, store generated
				    						key in keystore                */

  if (return_code != 0)
  {
      printf("Key generation failed for reason %d/%d\n\n",
	     return_code, reason_code);
      return ERROR;
  }
  else
  {
      printf("Key generated and stored in keystore\n");
      printf("SAPI returned %ld/%ld\n\n", return_code, reason_code);
      return OK;
  }
}