Example: Creating a PKA key with your Cryptographic Coprocessor

Change this 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 key store.                               */
/*                                                               */
/*  COPYRIGHT      5769-SS1 (c) IBM Corp 1999              */
/*                                                               */
/*  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 key store 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 key store 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 key store                                        */
/*-------------------------------------------------------------------*/
  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 key store for reason %d/%d\n\n",
	     return_code, reason_code);
      return ERROR;
  }
  else
  {
      printf("Record added to key store\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 key store                */

  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 key store\n");
      printf("SAPI returned %ld/%ld\n\n", return_code, reason_code);
      return OK;
  }
}