Sample C routine: Generating a MAC
To illustrate the practical application of CCA verb calls, this topic describes the sample C programming language routine included with the CCA Cryptographic Coprocessor Support Program.
There is also a sample program on the product Web site. That sample program can help you understand the performance of the CCA implementation.
The sample routine generates a message authentication code (MAC)
on a text string and then verifies the MAC. To generate and verify
the MAC, the routine:
- Calls the Key_Generate (CSNBKGN) verb to create a MAC and MACVER key pair.
- Calls the MAC_Generate (CSNBMGN) verb to generate a MAC on a text string with the MAC key.
- Calls the MAC_Verify (CSNBMVR) verb to verify the text string MAC with the MACVER key.
Verb | Entry-point name |
---|---|
Key_Generate | CSNBKGN |
MAC_Generate | CSNBMGN |
MAC_Verify | CSNBMVR |
/*********************************************************************/
/* */
/* Module Name: mac.c */
/* */
/* DESCRIPTIVE NAME: Cryptographic Coprocessor Support Program */
/* C language source code example */
/* */
/*-------------------------------------------------------------------*/
/* */
/* Licensed Materials - Property of IBM */
/* */
/* (C) Copyright IBM Corp. 1997-2010 All Rights Reserved */
/* */
/* US Government Users Restricted Rights - Use duplication or */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
/* */
/*-------------------------------------------------------------------*/
/* */
/* NOTICE TO USERS OF THE SOURCE CODE EXAMPLES */
/* */
/* The source code examples provided by IBM are only intended to */
/* assist in the development of a working software program. The */
/* source code examples do not function as written: additional */
/* code is required. In addition, the source code examples may */
/* not compile and/or bind successfully as written. */
/* */
/* International Business Machines Corporation provides the source */
/* code examples, both individually and as one or more groups, */
/* "as is" without warranty of any kind, either expressed or */
/* implied, including, but not limited to the implied warranties of */
/* merchantability and fitness for a particular purpose. The entire */
/* risk as to the quality and performance of the source code */
/* examples, both individually and as one or more groups, is with */
/* you. Should any part of the source code examples prove defective, */
/* you (and not IBM or an authorized dealer) assume the entire cost */
/* of all necessary servicing, repair or correction. */
/* */
/* IBM does not warrant that the contents of the source code */
/* examples, whether individually or as one or more groups, will */
/* meet your requirements or that the source code examples are */
/* error-free. */
/* */
/* IBM may make improvements and/or changes in the source code */
/* examples at any time. */
/* */
/* Changes may be made periodically to the information in the */
/* source code examples; these changes may be reported, for the */
/* sample code included herein, in new editions of the examples. */
/* */
/* References in the source code examples to IBM products, programs, */
/* or services do not imply that IBM intends to make these */
/* available in all countries in which IBM operates. Any reference */
/* to the IBM licensed program in the source code examples is not */
/* intended to state or imply that IBM's licensed program must be */
/* used. Any functionally equivalent program may be used. */
/* */
/*-------------------------------------------------------------------*/
/* */
/* This example program: */
/* */
/* 1) Calls the Key_Generate verb (CSNBKGN) to create a MAC (message */
/* authentication code) key token and a MACVER key token. */
/* */
/* 2) Calls the MAC_Generate verb (CSNBMGN) using the MAC key token */
/* from step 1 to generate a MAC on the supplied text string */
/* (INPUT_TEXT). */
/* */
/* 3) Calls the MAC_Verify verb (CSNBMVR) to verify the MAC for the */
/* same text string, using the MACVER key token created in */
/* step 1. */
/* */
/*********************************************************************/
#include <stdio.h>
#include <string.h>
#ifdef _AIX
#include <csufincl.h>
#elif __WINDOWS__
#include "csunincl.h"
#else
#include "csulincl.h" /* else linux */
#endif
/* Defines */
#define KEY_FORM "OPOP"
#define KEY_LENGTH "SINGLE "
#define KEY_TYPE_1 "MAC "
#define KEY_TYPE_2 "MACVER "
#define INPUT_TEXT "abcdefghijklmn0987654321"
#define MAC_PROCESSING_RULE "X9.9-1 "
#define SEGMENT_FLAG "ONLY "
#define MAC_LENGTH "HEX-9 "
#define MAC_BUFFER_LENGTH 10
void main()
{
static long return_code;
static long reason_code;
static unsigned char key_form[4];
static unsigned char key_length[8];
static unsigned char mac_key_type[8];
static unsigned char macver_key_type[8];
static unsigned char kek_key_id_1[64];
static unsigned char kek_key_id_2[64];
static unsigned char mac_key_id[64];
static unsigned char macver_key_id[64];
static long text_length;
static unsigned char text[26];
static long rule_array_count;
static unsigned char rule_array[3][8]; /* Max 3 rule array elements */
static unsigned char chaining_vector[18];
static unsigned char mac_value[MAC_BUFFER_LENGTH];
/* Print a banner */
printf("Cryptographic Coprocessor Support Program example program.\n");
/* Set up initial values for Key_Generate call */
return_code = 0;
reason_code = 0;
memcpy (key_form, KEY_FORM, 4); /* OPOP key pair */
memcpy (key_length, KEY_LENGTH, 8); /* Single-length keys */
memcpy (mac_key_type, KEY_TYPE_1, 8); /* 1st token, MAC key type */
memcpy (macver_key_type, KEY_TYPE_2, 8); /* 2nd token, MACVER key type */
memset (kek_key_id_1, 0x00, sizeof(kek_key_id_1)); /* 1st KEK not used */
memset (kek_key_id_2, 0x00, sizeof(kek_key_id_2)); /* 2nd KEK not used */
memset (mac_key_id, 0x00, sizeof(mac_key_id)); /* Init 1st key token */
memset (macver_key_id, 0x00, sizeof(macver_key_id)); /* Init 2nd key token */
/* Generate a MAC/MACVER operational key pair */
CSNBKGN(&return_code,
&reason_code,
NULL, /* exit_data_length */
NULL, /* exit_data */
key_form,
key_length,
mac_key_type,
macver_key_type,
kek_key_id_1,
kek_key_id_2,
mac_key_id,
macver_key_id);
/* Check the return/reason codes. Terminate if there is an error. */
if (return_code != 0 || reason_code != 0) {
printf ("Key_Generate failed: "); /* Print failing verb */
printf ("return_code = %ld, ", return_code); /* Print return code */
printf ("reason_code = %ld.\n", reason_code); /* Print reason code */
return;
}
else
printf ("Key_Generate successful.\n");
/* Set up initial values for MAC_Generate call */
return_code = 0;
reason_code = 0;
text_length = sizeof (INPUT_TEXT) - 1; /* Length of MAC text */
memcpy (text, INPUT_TEXT, text_length); /* Define MAC input text */
rule_array_count = 3; /* 3 rule array elements */
memset (rule_array, ' ', sizeof(rule_array)); /* Clear rule array */
memcpy (rule_array[0], MAC_PROCESSING_RULE, 8); /* 1st rule array element */
memcpy (rule_array[1], SEGMENT_FLAG, 8); /* 2nd rule array element */
memcpy (rule_array[2], MAC_LENGTH, 8); /* 3rd rule array element */
memset (chaining_vector, 0x00, 18); /* Clear chaining vector */
memset (mac_value, 0x00, sizeof(mac_value)); /* Clear MAC value */
/* Generate a MAC based on input text */
CSNBMGN ( &return_code,
&reason_code,
NULL, /* exit_data_length */
NULL, /* exit_data */
mac_key_id, /* Output from Key_Generate */
&text_length,
text,
&rule_array_count,
&rule_array[0][0],
chaining_vector,
mac_value);
/* Check the return/reason codes. Terminate if there is an error. */
if (return_code != 0 || reason_code != 0) {
printf ("MAC Generate Failed: "); /* Print failing verb */
printf ("return_code = %ld, ", return_code); /* Print return code */
printf ("reason_code = %ld.\n", reason_code); /* Print reason code */
return;
}
else {
printf ("MAC_Generate successful.\n");
printf ("MAC_value = %s\n", mac_value); /* Print MAC value (HEX-9) */
}
/* Set up initial values for MAC_Verify call */
return_code = 0;
reason_code = 0;
rule_array_count = 1; /* 1 rule array element */
memset (rule_array, ' ', sizeof(rule_array));/* Clear rule array */
memcpy (rule_array[0], MAC_LENGTH, 8); /* Rule array element */
/* (use default Ciphering */
/* Method and Segmenting */
/* Control) */
memset (chaining_vector, 0x00, 18); /* Clear the chaining vector */
/* Verify MAC value */
CSNBMVR (&return_code,
&reason_code,
NULL, /* exit_data_length */
NULL, /* exit_data */
macver_key_id, /* Output from Key_Generate */
&text_length, /* Same as for MAC_Generate */
text, /* Same as for MAC_Generate */
&rule_array_count,
&rule_array[0][0],
chaining_vector,
mac_value); /* Output from MAC_Generate */
/* Check the return/reason codes. Terminate if there is an error. */
if (return_code != 0 || reason_code != 0) {
printf ("MAC_Verify failed: "); /* Print failing verb */
printf ("return_code = %ld, ", return_code); /* Print return code */
printf ("reason_code = %ld.\n", reason_code); /* Print reason code */
return;
}
else /* No error occurred */
printf ("MAC_Verify successful.\n");
}