# HG changeset patch
# User Jack Magne <jmagne@redhat.com>
# Date 1504307754 25200
# Fri Sep 01 16:15:54 2017 -0700
# Node ID eec15518fd61f1d988c25b4de589555796f9e65f
# Parent 17d1d7b740ca5777fbcf8ee817a2f26b9c93593a
unwrapping of HMAC-SHA1 secret keys using AES wrapping and unwrapping
cfu on behalf of jmagne
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/pkcs11/PK11KeyWrapper.java
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.java Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.java Fri Sep 01 16:15:54 2017 -0700
@@ -588,6 +588,8 @@
return EncryptionAlgorithm.RC4;
} else if( type == SymmetricKey.AES ) {
return EncryptionAlgorithm.AES_128_ECB;
+ } else if( type == SymmetricKey.SHA1_HMAC) {
+ return HMACAlgorithm.SHA1;
} else {
Assert._assert( type == SymmetricKey.RC2 );
return EncryptionAlgorithm.RC2_CBC;
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/pkcs11/PK11MessageDigest.c
--- a/org/mozilla/jss/pkcs11/PK11MessageDigest.c Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11MessageDigest.c Fri Sep 01 16:15:54 2017 -0700
@@ -67,19 +67,19 @@
}
/* copy the key, setting the CKA_SIGN attribute */
- /*
+
newKey = PK11_CopySymKeyForSigning(origKey, mech);
+
+ /* For some key on the hsm, this call could fail, but the key may work anyway */
+
if( newKey == NULL ) {
- JSS_throwMsg(env, DIGEST_EXCEPTION,
- "Unable to set CKA_SIGN attribute on symmetric key");
- goto finish;
+ newKey = origKey;
}
- */
param.data = NULL;
param.len = 0;
- context = PK11_CreateContextBySymKey(mech, CKA_SIGN, origKey, ¶m);
+ context = PK11_CreateContextBySymKey(mech, CKA_SIGN, newKey, ¶m);
if( context == NULL ) {
JSS_throwMsg(env, DIGEST_EXCEPTION,
"Unable to initialize digest context");
@@ -88,7 +88,7 @@
contextObj = JSS_PK11_wrapCipherContextProxy(env, &context);
finish:
- if(newKey) {
+ if(newKey && (newKey != origKey)) {
/* SymKeys are ref counted, and the context will free it's ref
* when it is destroyed */
PK11_FreeSymKey(newKey);
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/tests/HmacTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/org/mozilla/jss/tests/HmacTest.java Fri Sep 01 16:15:54 2017 -0700
@@ -0,0 +1,119 @@
+
+package org.mozilla.jss.tests;
+
+
+import java.security.Key;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.SymmetricKey;
+
+
+public class HmacTest {
+
+ private static final String INTERNAL_KEY_STORAGE_TOKEN =
+ new CryptoManager.InitializationValues("").getInternalKeyStorageTokenDescription().trim();
+
+ private static final String NSS_DATABASE_DIR = "sql:data";
+ private static final String PROVIDER = "Mozilla-JSS";
+
+
+ public static void main(String[] args)
+ {
+
+ String algorithm = "hmac-sha1";
+
+ try {
+ configureCrypto(args);
+
+ Mac mac = Mac.getInstance(algorithm, PROVIDER);
+
+ byte[] keyData = new byte[16];
+ Key key = importHmacSha1Key(keyData);
+
+ mac.init(key);
+
+ doHMAC(mac,"Dogtag rules!");
+
+ System.out.println("Done");
+
+ System.exit(0);
+ } catch (Exception e) {
+ System.exit(1);
+ }
+ }
+
+ private static void configureCrypto(String[] args)
+ throws Exception {
+
+ CryptoManager.InitializationValues initializationValues =
+ new CryptoManager.InitializationValues(args[0]);
+
+ CryptoManager.initialize(initializationValues);
+
+ CryptoManager cryptoManager = CryptoManager.getInstance();
+
+ CryptoToken cryptoToken =
+ cryptoManager.getTokenByName(INTERNAL_KEY_STORAGE_TOKEN);
+
+ cryptoManager.setThreadToken(cryptoToken);
+ }
+
+ private static Key importHmacSha1Key(byte[] key)
+ throws Exception {
+
+ final String WRAPPING_ALGORITHM = "AES/CBC/PKCS5Padding";
+
+ Key wrappingKey = getWrappingKey();
+
+ byte[] iv = new byte[16];
+ IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
+
+ Cipher wrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER);
+ wrappingCipher.init(Cipher.ENCRYPT_MODE, wrappingKey, ivParameterSpec);
+
+ byte[] wrappedKeyData = wrappingCipher.doFinal(key);
+
+ Cipher unwrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER);
+ unwrappingCipher.init(Cipher.UNWRAP_MODE, wrappingKey, ivParameterSpec);
+
+ return (SecretKey) unwrappingCipher.unwrap(wrappedKeyData,
+ SymmetricKey.SHA1_HMAC.toString(),
+ Cipher.SECRET_KEY);
+ }
+
+ private static synchronized Key getWrappingKey()
+ throws Exception {
+
+ final String keyGenAlgorithm = "AES";
+ final int wrappingKeyLength = 256;
+
+ KeyGenerator keyGen = KeyGenerator.getInstance(keyGenAlgorithm, PROVIDER);
+ keyGen.init(wrappingKeyLength);
+ return keyGen.generateKey();
+ }
+
+ public static void doHMAC(Mac mozillaHmac, String clearText)
+ throws Exception {
+ byte[] mozillaHmacOut;
+
+ //Get the Mozilla HMAC
+ mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes());
+
+ if (mozillaHmacOut.length == mozillaHmac.getMacLength()) {
+ System.out.println(PROVIDER + " supports " +
+ mozillaHmac.getAlgorithm() + " and the output size is " + mozillaHmac.getMacLength());
+ } else {
+ throw new Exception("ERROR: hmac output size is " +
+ mozillaHmacOut.length + ", should be " +
+ mozillaHmac.getMacLength());
+ }
+ }
+
+
+}
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/tests/all.pl
--- a/org/mozilla/jss/tests/all.pl Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/tests/all.pl Fri Sep 01 16:15:54 2017 -0700
@@ -492,6 +492,10 @@
$command = "$java -cp $jss_classpath org.mozilla.jss.tests.HMACTest $testdir $pwfile";
run_test($testname, $command);
+$testname = "HMAC Unwrap";
+$command = "$java -cp $jss_classpath org.mozilla.jss.tests.HmacTest $testdir $pwfile";
+run_test($testname, $command);
+
$testname = "KeyWrapping ";
$command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCAKeyWrap $testdir $pwfile";
run_test($testname, $command);