Skip to content

Commit

Permalink
Updated p11kcv to support non-null input buffers to HMAC
Browse files Browse the repository at this point in the history
  • Loading branch information
keldonin committed Apr 12, 2021
1 parent 447b907 commit 5771893
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

=======
# [2.3.0]
### Added
- added the ability to specify a buffer length, when performing HMAC key check values (default is 0).

# [2.2.0]
### Added
- p11kcv will compute a Key Check Value on `CK_GENERIC_SECRET` keys as well. These are mapped to HMAC-SHA256.
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dnl limitations under the License.


AC_PREREQ([2.64])
AC_INIT([pkcs11-tools], [2.2.0], [https://github.com/Mastercard/pkcs11-tools/issues], [pkcs11-tools], [https://github.com/Mastercard/pkcs11-tools])
AC_INIT([pkcs11-tools], [2.3.0], [https://github.com/Mastercard/pkcs11-tools/issues], [pkcs11-tools], [https://github.com/Mastercard/pkcs11-tools])
AC_CONFIG_MACRO_DIR([m4])

dnl adding AM_MAINTAINER_MODE to address autotools issues with git
Expand Down
7 changes: 6 additions & 1 deletion docs/MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,12 @@ For generating HMAC key on nCipher, you need to use one of the following key typ
using `p11keygen`, it is possible to generate a session key and wrap it immediately under one or several wrapping keys. To achieve this, you simply need to add the `-W` optional parameter, followed by the wrapping parameters string, as explained in `p11wrap`. Note that by default, `p11keygen` will attempt to store a copy of the session key on the token. To prevent this (some PKCS\#11 library do not support this), add the `-r` optional parameter.

## p11kcv
Computes the key check value of a symmetric key and prints it. This will work only on symmetric keys (`des` and `aes` keys).
Computes the key check value of a symmetric key and prints it. This will work only on secret keys, i.e. DES, AES and HMAC keys.

The key check value is computed as follows:
- For DES keys, it performs a a signature (MACing) or an encryption on a block of 8 zeroized bytes, and outputting the 3 first ones.
- For AES keys, it performs a a signature (MACing) or an encryption on a block of 16 zeroized bytes, and outputting the 3 first ones.
- For HMAC keys, the key check value is computed by HMACing a null-length buffer. Alternatively, it is possible to specify a length, using the `-b` optional argument, in which case a zeroized buffer of the specified lenght is used as input to the HMAC.

## p11req
Generate a PKCS\#10 CSR. Important options are:
Expand Down
3 changes: 2 additions & 1 deletion include/pkcs11lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,8 @@ func_rc pkcs11_info_ecsupport(pkcs11Context *p11Context);
func_rc pkcs11_change_object_attributes(pkcs11Context *p11Context, char *label, CK_ATTRIBUTE *attr, size_t cnt, int interactive );

/* kcv functions */
void pkcs11_display_kcv( pkcs11Context *p11Context, char *label );
#define MAX_KCV_CLEARTEXT_SIZE 256
void pkcs11_display_kcv( pkcs11Context *p11Context, char *label, unsigned hmacdatasize );

/* wrap/unwrap functions */
func_rc pkcs11_prepare_wrappingctx(wrappedKeyCtx *wctx, char *wrappingjob);
Expand Down
50 changes: 27 additions & 23 deletions lib/pkcs11_kcv.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@

/* target must point to a location with at least 3 bytes left */

void pkcs11_display_kcv( pkcs11Context *p11Context, char *label )
void pkcs11_display_kcv( pkcs11Context *p11Context, char *label, unsigned hmacdatasize )
{

pkcs11Search *search=NULL;
pkcs11IdTemplate *idtmpl=NULL;
CK_OBJECT_HANDLE *hndl_array=NULL;


if(hmacdatasize>MAX_KCV_CLEARTEXT_SIZE) {
fprintf(stderr, "Invalid HMAC block size specified (%d), must be between 0 and %d\n", hmacdatasize, MAX_KCV_CLEARTEXT_SIZE );
}
/* trick: we treat "cert", "pubk", "prvk", "seck" and "data" in front of the templating system */
/* so these specific labels can be used as shortcut for the corresponding object classes */

Expand Down Expand Up @@ -91,9 +95,9 @@ void pkcs11_display_kcv( pkcs11Context *p11Context, char *label )
if( attrs!=NULL) {
if (pkcs11_read_attr_from_handle (attrs, hndl_array[j]) == CK_TRUE) {
CK_RV rv;
CK_BYTE cleartext[16];
CK_BYTE encrypted[64];
CK_ULONG cleartext_len, encrypted_len;
CK_BYTE cleartext[MAX_KCV_CLEARTEXT_SIZE];
CK_BYTE processed[64];
CK_ULONG cleartext_len, processed_len;

CK_MECHANISM des_ecb = { CKM_DES_ECB, NULL_PTR, 0 };
CK_MECHANISM des3_ecb = { CKM_DES3_ECB, NULL_PTR, 0 };
Expand Down Expand Up @@ -130,64 +134,64 @@ void pkcs11_display_kcv( pkcs11Context *p11Context, char *label )
case CKK_DES:
mechanism = &des_ecb;
cleartext_len = 8L;
encrypted_len = 8L;
processed_len = 8L;
keytypestr = "DES, single length";
whattodo=encrypt;
break;

case CKK_DES2:
mechanism = &des3_ecb;
cleartext_len = 8L;
encrypted_len = 8L;
processed_len = 8L;
keytypestr = "3DES, double length";
whattodo=encrypt;
break;

case CKK_DES3:
mechanism = &des3_ecb;
cleartext_len = 8L;
encrypted_len = 8L;
processed_len = 8L;
keytypestr = "3DES, triple length";
whattodo=encrypt;
break;

case CKK_AES:
mechanism = &aes_ecb;
cleartext_len = 16L;
encrypted_len = 16L;
processed_len = 16L;
keytypestr = "AES";
whattodo=encrypt;
break;

case CKK_SHA_1_HMAC:
mechanism = &sha1_hmac;
cleartext_len = 0L;
encrypted_len = 20L;
cleartext_len = hmacdatasize;
processed_len = 20L;
keytypestr = "HMAC(SHA1)";
whattodo=sign;
break;

case CKK_SHA256_HMAC:
case CKK_GENERIC_SECRET:
mechanism = &sha256_hmac;
cleartext_len = 0L;
encrypted_len = 32L;
cleartext_len = hmacdatasize;
processed_len = 32L;
keytypestr = "HMAC(SHA256)";
whattodo=sign;
break;

case CKK_SHA384_HMAC:
mechanism = &sha384_hmac;
cleartext_len = 0L;
encrypted_len = 48L;
cleartext_len = hmacdatasize;
processed_len = 48L;
keytypestr = "HMAC(SHA384)";
whattodo=sign;
break;

case CKK_SHA512_HMAC:
mechanism = &sha512_hmac;
cleartext_len = 0L;
encrypted_len = 64L;
cleartext_len = hmacdatasize;
processed_len = 64L;
keytypestr = "HMAC(SHA384)";
whattodo=sign;
break;
Expand Down Expand Up @@ -220,13 +224,13 @@ void pkcs11_display_kcv( pkcs11Context *p11Context, char *label )
p11Context->FunctionList.C_Encrypt ( p11Context->Session,
cleartext,
cleartext_len,
encrypted,
&encrypted_len ) :
processed,
&processed_len ) :
p11Context->FunctionList.C_Sign ( p11Context->Session,
cleartext,
cleartext_len,
encrypted,
&encrypted_len );
processed,
&processed_len );
if(rv!=CKR_OK) {
pkcs11_error(rv, whattodo == encrypt ? "C_Encrypt" : "C_Sign");
pkcs11_delete_attrlist(attrs);
Expand All @@ -237,9 +241,9 @@ void pkcs11_display_kcv( pkcs11Context *p11Context, char *label )
printf("%-*s: KCV = %02.2x%02.2x%02.2x (%s)\n",
LABEL_WIDTH,
buffer,
encrypted[0],
encrypted[1],
encrypted[2],
processed[0],
processed[1],
processed[2],
keytypestr);
}
pkcs11_delete_attrlist(attrs);
Expand Down
15 changes: 12 additions & 3 deletions src/p11kcv.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ void print_usage(char *);
int main( int argc, char **argv);




void print_usage(char *progname)
{
fprintf( stderr,
Expand All @@ -50,6 +52,7 @@ void print_usage(char *progname)
" -t <token label> : if present, -s option is ignored\n"
" -p <token PIN> | :::exec:<command> | :::nologin\n"
" -S : login with SO privilege\n"
" -b <len>: size of buffer to HMAC, for HMAC keys (max: %d, default: 0)\n"
" -h : print usage information\n"
" -V : print version information\n"
"|\n"
Expand Down Expand Up @@ -86,7 +89,8 @@ void print_usage(char *progname)
" PKCS11PASSWORD : password\n"
" overriden by option -p\n"
"\n"
, pkcs11_ll_basename(progname) );
, pkcs11_ll_basename(progname),
MAX_KCV_CLEARTEXT_SIZE);

exit( RC_ERROR_USAGE );
}
Expand All @@ -105,6 +109,7 @@ int main( int argc, char ** argv )
int interactive = 1;
char * tokenlabel = NULL;
int so=0;
unsigned hmacdatasize = 0;

pkcs11Context * p11Context = NULL;
func_rc retcode = rc_error_usage;
Expand All @@ -121,7 +126,7 @@ int main( int argc, char ** argv )
password = getenv("PKCS11PASSWORD");

/* get the command-line arguments */
while ( ( argnum = getopt( argc, argv, "l:m:p:s:t:ShV" ) ) != -1 )
while ( ( argnum = getopt( argc, argv, "l:m:p:s:t:Sb:hV" ) ) != -1 )
{
switch ( argnum )
{
Expand Down Expand Up @@ -149,6 +154,10 @@ int main( int argc, char ** argv )
slot = -1;
break;

case 'b':
hmacdatasize=strtoul(optarg, NULL, 10);
break;

case 'S':
so=1;
break;
Expand Down Expand Up @@ -195,7 +204,7 @@ int main( int argc, char ** argv )
{
char *label;
for(label=argv[optind];optind<argc; optind++) {
pkcs11_display_kcv(p11Context, argv[optind]);
pkcs11_display_kcv(p11Context, argv[optind], hmacdatasize);
}

pkcs11_close_session( p11Context );
Expand Down

0 comments on commit 5771893

Please sign in to comment.