diff options
author | Jack Magne <jmagne@localhost.localdomain> | 2015-03-12 19:08:41 -0700 |
---|---|---|
committer | Jack Magne <jmagne@localhost.localdomain> | 2015-03-17 12:44:28 -0700 |
commit | 87ffc7a341860f3f1ece434e90e4bc33a02b8155 (patch) | |
tree | d833d1868284ce2c3865a674aca0bad66a0f7ebd /base/symkey/src | |
parent | f98e599b1e95572a589b8813bc6cb0c2e70fdd0b (diff) | |
download | pki-87ffc7a341860f3f1ece434e90e4bc33a02b8155.tar.gz pki-87ffc7a341860f3f1ece434e90e4bc33a02b8155.tar.xz pki-87ffc7a341860f3f1ece434e90e4bc33a02b8155.zip |
NISTSP8000 feature.
Implementation of the nistSP800 dervication feature.
Works for both supported scp01 cards and scp02 cards.
During the various session key and key upgrade functions, the nist dervication code is being called.
Review comments addressed
Cleanup of some input validation on the TKS.
Added some sanity checking on the TPS side for key versions and token cuid's and kdd's.
Final review comments.
Fixed issue with extracting the kdd from the AppletInfo class.
Fixed issue with sending the KDD to the encryptData TKS servlet.
Added requested entries to the CS.cfg .
Diffstat (limited to 'base/symkey/src')
-rw-r--r-- | base/symkey/src/com/netscape/symkey/SessionKey.cpp | 176 | ||||
-rw-r--r-- | base/symkey/src/com/netscape/symkey/SessionKey.java | 5 | ||||
-rw-r--r-- | base/symkey/src/com/netscape/symkey/SymKey.cpp | 15 |
3 files changed, 123 insertions, 73 deletions
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.cpp b/base/symkey/src/com/netscape/symkey/SessionKey.cpp index 610928099..d3ac01216 100644 --- a/base/symkey/src/com/netscape/symkey/SessionKey.cpp +++ b/base/symkey/src/com/netscape/symkey/SessionKey.cpp @@ -674,12 +674,12 @@ extern "C" * Signature: ([B[B[B[B)[B */ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKeySCP02 - (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring, jstring); + (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyte, jboolean, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring, jstring); #ifdef __cplusplus } #endif #define KEYLENGTH 16 -extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKeySCP02(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray keyInfo, jbyteArray CUID, jbyteArray devKeyArray, jbyteArray sequenceCounter, jbyteArray derivationConstant, jstring useSoftToken_s, jstring keySet, jstring sharedSecretKeyName) +extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKeySCP02(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray keyInfo, jbyte nistSP800_108KdfOnKeyVersion, jboolean nistSP800_108KdfUseCuidAsKdd, jbyteArray CUID, jbyteArray KDD, jbyteArray devKeyArray, jbyteArray sequenceCounter, jbyteArray derivationConstant, jstring useSoftToken_s, jstring keySet, jstring sharedSecretKeyName) { /* hardcode permanent dev key */ jbyte *dev_key = NULL; @@ -707,6 +707,10 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp PK11SymKey *symkey16 = NULL; PK11SymKey *devKey = NULL; + // KDF output keys + PK11SymKey* macKey = NULL; + PK11SymKey* encKey = NULL; + PK11SymKey* kekKey = NULL; BYTE devData[KEYLENGTH]; char keyname[KEYNAMELENGTH]; @@ -730,6 +734,10 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp jbyte *handleBytes=NULL; jbyte * cuidValue = NULL; + jsize cuidValue_len = -1; + + jbyte* kddValue = NULL; + jsize kddValue_len = -1; jbyte *sc = NULL; int sc_len = 0; @@ -799,12 +807,28 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp if ( CUID != NULL ) { cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL); + cuidValue_len = env->GetArrayLength(CUID); } if( cuidValue == NULL) { goto done; } + if ( cuidValue_len <= 0){ // check that CUID is at least 1 byte in length + goto done; + } + + if ( KDD != NULL ){ + kddValue = env->GetByteArrayElements(KDD, NULL); + kddValue_len = env->GetArrayLength(KDD); + } + if ( kddValue == NULL ){ + goto done; + } + if ( kddValue_len != static_cast<jsize>(NistSP800_108KDF::KDD_SIZE_BYTES) ){ // check that KDD is expected size + goto done; + } + if(tokenName) { tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL); @@ -843,8 +867,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp break; } - GetDiversificationData(cuidValue,devData,kType); - PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKeySCP02! keyName %s keyVersion[0] %d keyVersion[1] %d \n",keyname,(int) keyVersion[0],(int) keyVersion[1]); if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 ) || @@ -868,7 +890,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp goto done; } - //In the enc key case create the auth as well, we may need it later. + //In the enc key case create the auth developer as well, we may need it later. if(kType == enc) { @@ -883,7 +905,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp PK11_FreeSymKey(authKey); authKey = NULL; - } }else @@ -895,23 +916,89 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp goto done; } - devKey =ComputeCardKeyOnToken(masterKey,devData,2); - if(devKey == NULL) - { - goto done; - } + + BYTE nistSP800_108KdfOnKeyVersion_byte = static_cast<BYTE>(nistSP800_108KdfOnKeyVersion); + BYTE requestedKeyVersion_byte = static_cast<BYTE>(keyVersion[0]); + // if requested key version meets setting value, use NIST SP800-108 KDF + if (NistSP800_108KDF::useNistSP800_108KDF(nistSP800_108KdfOnKeyVersion_byte, requestedKeyVersion_byte) == true){ + PR_fprintf(PR_STDOUT,"ComputeSessionKeySCP02 NistSP800_108KDF code: Using NIST SP800-108 KDF.\n"); + + jbyte* context_jbyte = NULL; + jsize context_len_jsize = 0; + if (nistSP800_108KdfUseCuidAsKdd == JNI_TRUE){ + context_jbyte = cuidValue; + context_len_jsize = cuidValue_len; + }else{ + context_jbyte = kddValue; + context_len_jsize = kddValue_len; + } + + const BYTE* const context = reinterpret_cast<const BYTE*>(context_jbyte); + + const size_t context_len = static_cast<size_t>(context_len_jsize); + if (context_len > 0x000000FF){ // sanity check (CUID should never be larger than 255 bytes) + PR_fprintf(PR_STDERR, "ComputeSessionKeySCP02 NistSP800_108KDF code: Error; context_len larger than 255 bytes.\n"); + goto done; + } + + try{ + NistSP800_108KDF::ComputeCardKeys(masterKey, context, context_len, &encKey, &macKey, &kekKey); + }catch(std::runtime_error& ex){ + PR_fprintf(PR_STDERR, "ComputeSessionKeySCP02 NistSP800_108KDF code: Exception invoking NistSP800_108KDF::ComputeCardKeys: "); + PR_fprintf(PR_STDERR, "%s\n", ex.what() == NULL ? "null" : ex.what()); + goto done; + }catch(...){ + PR_fprintf(PR_STDERR, "ComputeSessionKeySCP02 NistSP800_108KDF code: Unknown exception invoking NistSP800_108KDF::ComputeCardKeys.\n"); + goto done; + } + + + //Decide upon the key we actually are asking for. + if(kType == mac ) { + PR_fprintf(PR_STDOUT,"SessionKey.ComputeSessionKeySCP02! Getting mac key. \n"); + devKey = macKey; + macKey = NULL; + } + + if(kType == enc) { + PR_fprintf(PR_STDOUT,"SessionKey.ComputeSessionKeySCP02! Getting enc key. \n"); + devKey = encKey; + encKey = NULL; + + } + + if(kType == kek) { + PR_fprintf(PR_STDOUT,"SessionKey.ComputeSessionKeySCP02! Getting kek key. \n"); + devKey = kekKey; + kekKey = NULL; + } + + } else { + + // Do what the original code did, using the standard routines. + PR_fprintf(PR_STDOUT,"ComputeSessionKeySCP02 NistSP800_108KDF code: Using original KDF.\n"); + GetDiversificationData(cuidValue,devData,kType); + + devKey =ComputeCardKeyOnToken(masterKey,devData,2); + + } + + if(devKey == NULL) + { + goto done; + } - symkey = DeriveKeySCP02(devKey, Buffer((BYTE*)sc, sc_len), Buffer((BYTE*)dc, dc_len)); + symkey = DeriveKeySCP02(devKey, Buffer((BYTE*)sc, sc_len), Buffer((BYTE*)dc, dc_len)); - if(symkey == NULL) - { - goto done; - } + if(symkey == NULL) + { + goto done; + } } //Now wrap the key for the trip back to TPS with shared secret transport key symkey16 = NULL; - transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL)); + transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL)); if ( transportKey == NULL ) { PR_fprintf(PR_STDERR, "Can't find shared secret transport key! \n"); goto done; @@ -956,6 +1043,19 @@ done: symkey = NULL; } + if( macKey ) { + PK11_FreeSymKey( macKey); + macKey = NULL; + } + if ( encKey ) { + PK11_FreeSymKey(encKey); + encKey = NULL; + } + if ( kekKey ) { + PK11_FreeSymKey(kekKey); + kekKey = NULL; + } + if ( transportKey ) { PK11_FreeSymKey( transportKey ); transportKey = NULL; @@ -1023,8 +1123,6 @@ done: } - - //================================================================================= #ifdef __cplusplus extern "C" @@ -1053,14 +1151,11 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp return NULL; } - unsigned char input[KEYLENGTH] = {0}; - int i = 0; SECItem wrappedKeyItem = { siBuffer, NULL , 0}; SECItem noParams = { siBuffer, NULL, 0 }; SECStatus wrapStatus = SECFailure; - char *keyNameChars=NULL; char *tokenNameChars=NULL; PK11SlotInfo *slot = NULL; @@ -1191,17 +1286,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp goto done; } - - /* copy card and host challenge into input buffer */ - for (i = 0; i < 8; i++) - { - input[i] = cc[i]; - } - for (i = 0; i < 8; i++) - { - input[8+i] = hc[i]; - } - // AC: KDF SPEC CHANGE: Moved this call down. (We don't necessarily need it anymore depending on the KDF we're going to use.) //GetDiversificationData(cuidValue,macData,mac);//keytype is mac @@ -1483,8 +1567,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp return NULL; } - unsigned char input[KEYLENGTH] = {0}; - int i = 0; SECItem wrappedKeyItem = { siBuffer, NULL , 0}; SECItem noParams = { siBuffer, NULL, 0 }; @@ -1605,17 +1687,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp goto done; } - - /* copy card and host challenge into input buffer */ - for (i = 0; i < 8; i++) - { - input[i] = cc[i]; - } - for (i = 0; i < 8; i++) - { - input[8+i] = hc[i]; - } - // AC: KDF SPEC CHANGE: Moved this call down. (We don't necessarily need it anymore depending on the KDF we're going to use.) //GetDiversificationData(cuidValue,encData,enc); @@ -1897,8 +1968,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute keySetString = (char *) DEFKEYSET_NAME; } - unsigned char input[KEYLENGTH] = {0}; - int i; jobject keyObj = NULL; jbyte *cc = NULL; @@ -1980,17 +2049,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute goto done; } - - /* copy card and host challenge into input buffer */ - for (i = 0; i < 8; i++) - { - input[i] = cc[i]; - } - for (i = 0; i < 8; i++) - { - input[8+i] = hc[i]; - } - // AC: KDF SPEC CHANGE: Moved this call down. (We don't necessarily need it anymore depending on the KDF we're going to use.) //GetDiversificationData(cuidValue,kekData,kek);//keytype is kek diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.java b/base/symkey/src/com/netscape/symkey/SessionKey.java index 7a32de60c..d31740e93 100644 --- a/base/symkey/src/com/netscape/symkey/SessionKey.java +++ b/base/symkey/src/com/netscape/symkey/SessionKey.java @@ -79,7 +79,10 @@ public class SessionKey { public static native byte[] ComputeSessionKeySCP02(String tokenName, String keyName, byte[] keyInfo, + byte nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE + boolean nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE byte[] CUID, + byte[] KDD, byte[] devKeyArray, byte[] sequenceCounter, byte[] derivationConstant, @@ -180,7 +183,7 @@ public class SessionKey { byte[] oldKeyInfo, // AC: KDF SPEC CHANGE // AC: BUGFIX for key versions higher than 09: We need to specialDecode keyInfo parameters before sending them into symkey! This means the parameters must be jbyteArray's // -- Changed parameter "jstring keyInfo" to "jbyteArray newKeyInfo" - byte[] newKeyInfo, + byte[] newKeyInfo, byte nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE boolean nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE byte[] CUIDValue, diff --git a/base/symkey/src/com/netscape/symkey/SymKey.cpp b/base/symkey/src/com/netscape/symkey/SymKey.cpp index 8890ac3b5..02465de13 100644 --- a/base/symkey/src/com/netscape/symkey/SymKey.cpp +++ b/base/symkey/src/com/netscape/symkey/SymKey.cpp @@ -535,7 +535,6 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI static SECItem noParams = { siBuffer, NULL, 0 }; unsigned char *in = data; PK11SymKey *tmpkey = NULL; - unsigned char icv[EIGHT_BYTES] = { 0 }; unsigned char wrappedkey[DES3_LENGTH]; SECItem wrappeditem = { siBuffer, NULL, 0 }; @@ -825,8 +824,8 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek Buffer kc_kek_key(3); Buffer result; - //Buffer *dumpBuffer = NULL; - //int showDerivedKeys = 0; + Buffer *dumpBuffer = NULL; + int showDerivedKeys = 0; PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys! Protocol: %d \n",protocol); @@ -873,8 +872,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek authKey16 = PK11_Derive(new_auth_key, CKM_EXTRACT_KEY_FROM_KEY, ¶msItem, CKA_ENCRYPT, CKA_DERIVE, 16); - /* - if(showDerivedKeys == 1) { SECItem *keyData = NULL; PK11_ExtractKeyValue( authKey16 ); @@ -886,8 +883,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek dumpBuffer = NULL; } - */ - if ( authKey16 == NULL ) { PR_fprintf(PR_STDERR,"Error deriving authKey16. Error %d \n", PR_GetError()); goto done; @@ -908,7 +903,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek goto done; } - /* if(showDerivedKeys == 1) { SECItem *keyData = NULL; @@ -921,7 +915,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek dumpBuffer = NULL; } - */ wrappedKeyItem.data = (unsigned char *) encrypted_mac_key; wrappedKeyItem.len = encrypted_mac_key.size(); @@ -939,8 +932,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek PR_fprintf(PR_STDERR,"Error deriving kekKey16. Error %d \n", PR_GetError()); } - /* - if(showDerivedKeys == 1) { SECItem *keyData = NULL; PK11_ExtractKeyValue( kekKey16 ); @@ -951,8 +942,6 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek delete dumpBuffer; dumpBuffer = NULL; } - - */ wrappedKeyItem.data = (unsigned char *) encrypted_kek_key; wrappedKeyItem.len = encrypted_mac_key.size(); |