summaryrefslogtreecommitdiffstats
path: root/base/symkey/src
diff options
context:
space:
mode:
authorJack Magne <jmagne@localhost.localdomain>2015-03-12 19:08:41 -0700
committerJack Magne <jmagne@localhost.localdomain>2015-03-17 12:44:28 -0700
commit87ffc7a341860f3f1ece434e90e4bc33a02b8155 (patch)
treed833d1868284ce2c3865a674aca0bad66a0f7ebd /base/symkey/src
parentf98e599b1e95572a589b8813bc6cb0c2e70fdd0b (diff)
downloadpki-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.cpp176
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.java5
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.cpp15
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, &paramsItem, 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();