Blame SOURCES/jss-PBE-padded-block-cipher-enhancements.patch

50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504894163 25200
50aabd
#      Fri Sep 08 11:09:23 2017 -0700
50aabd
# Node ID 3629b598a9ce73e83c7896407e3ca820f6383750
50aabd
# Parent  eec15518fd61f1d988c25b4de589555796f9e65f
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
  patch jss-ftweedal-0006-PBEKeyGenParams-allow-specifying-encryption-algorith.patch
50aabd
50aabd
Allow specifying an target encryption algorithm in PBEKeyGenParams;
50aabd
 if the PBE algorithm does not imply a particular cipher, this is needed
50aabd
 to determine the size of the key to generate
50aabd
50aabd
cfu for ftweedale
50aabd
50aabd
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/crypto/PBEKeyGenParams.java
50aabd
--- a/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 01 16:15:54 2017 -0700
50aabd
+++ b/org/mozilla/jss/crypto/PBEKeyGenParams.java	Fri Sep 08 11:09:23 2017 -0700
50aabd
@@ -13,6 +13,7 @@
50aabd
     private Password pass;
50aabd
     private byte[] salt;
50aabd
     private int iterations;
50aabd
+    private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC;
50aabd
 
50aabd
     private PBEKeyGenParams() { }
50aabd
 
50aabd
@@ -40,7 +41,8 @@
50aabd
     }
50aabd
 
50aabd
     /**
50aabd
-     * Creates PBE parameters.
50aabd
+     * Creates PBE parameters using default encryption algorithm
50aabd
+     * (DES3_EDE3_CBC).
50aabd
      *
50aabd
      * @param pass The password. It will be cloned, so the
50aabd
      *      caller is still responsible for clearing it. It must not be null.
50aabd
@@ -60,6 +62,33 @@
50aabd
     }
50aabd
 
50aabd
     /**
50aabd
+     * Creates PBE parameters using default encryption algorithm
50aabd
+     * (DES3_EDE3_CBC).
50aabd
+     *
50aabd
+     * @param pass The password. It will be cloned, so the
50aabd
+     *      caller is still responsible for clearing it. It must not be null.
50aabd
+     * @param salt The salt for the PBE algorithm. Will not be cloned.
50aabd
+     *      Must not be null. It is the responsibility of the caller to
50aabd
+     *      use the right salt length for the algorithm. Most algorithms
50aabd
+     *      use 8 bytes of salt.
50aabd
+     * @param iterations The iteration count for the PBE algorithm.
50aabd
+     * @param encAlg The encryption algorithm.  This is used with SOME
50aabd
+     *      PBE algorithms for determining the KDF output length.
50aabd
+     */
50aabd
+    public PBEKeyGenParams(
50aabd
+            char[] pass, byte[] salt, int iterations,
50aabd
+            EncryptionAlgorithm encAlg) {
50aabd
+        if (pass == null || salt == null) {
50aabd
+            throw new NullPointerException();
50aabd
+        }
50aabd
+        this.pass = new Password((char[]) pass.clone());
50aabd
+        this.salt = salt;
50aabd
+        this.iterations = iterations;
50aabd
+        if (encAlg != null)
50aabd
+            this.encryptionAlgorithm = encAlg;
50aabd
+    }
50aabd
+
50aabd
+    /**
50aabd
      * Returns a reference to the password, not a copy.
50aabd
      */
50aabd
     public Password getPassword() {
50aabd
@@ -81,6 +110,14 @@
50aabd
     }
50aabd
 
50aabd
     /**
50aabd
+     * The encryption algorithm is used with SOME PBE algorithms for
50aabd
+     * determining the KDF output length.
50aabd
+     */
50aabd
+    public EncryptionAlgorithm getEncryptionAlgorithm() {
50aabd
+        return encryptionAlgorithm;
50aabd
+    }
50aabd
+
50aabd
+    /**
50aabd
      * Clears the password. This should be called when this object is no
50aabd
      * longer needed so the password is not left around in memory.
50aabd
      */
50aabd
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 01 16:15:54 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.c	Fri Sep 08 11:09:23 2017 -0700
50aabd
@@ -246,9 +246,9 @@
50aabd
  *
50aabd
  */
50aabd
 JNIEXPORT jobject JNICALL
50aabd
-Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE
50aabd
-    (JNIEnv *env, jclass clazz, jobject token, jobject alg, jbyteArray passBA,
50aabd
-    jbyteArray saltBA, jint iterationCount)
50aabd
+Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE(
50aabd
+    JNIEnv *env, jclass clazz, jobject token, jobject alg, jobject encAlg,
50aabd
+    jbyteArray passBA, jbyteArray saltBA, jint iterationCount)
50aabd
 {
50aabd
     PK11SlotInfo *slot=NULL;
50aabd
     PK11SymKey *skey=NULL;
50aabd
@@ -299,12 +299,15 @@
50aabd
         oidTag = JSS_getOidTagFromAlg(env, alg);
50aabd
         PR_ASSERT(oidTag != SEC_OID_UNKNOWN);
50aabd
 
50aabd
+        SECOidTag encAlgOidTag = JSS_getOidTagFromAlg(env, encAlg);
50aabd
+        PR_ASSERT(encAlgOidTag != SEC_OID_UNKNOWN);
50aabd
+
50aabd
         /* create algid */
50aabd
         algid = PK11_CreatePBEV2AlgorithmID(
50aabd
             oidTag,
50aabd
-            SEC_OID_DES_EDE3_CBC,
50aabd
+            encAlgOidTag,
50aabd
             SEC_OID_HMAC_SHA1,
50aabd
-            168/8,
50aabd
+            0,
50aabd
             iterationCount,
50aabd
             salt);
50aabd
 
50aabd
diff -r eec15518fd61 -r 3629b598a9ce org/mozilla/jss/pkcs11/PK11KeyGenerator.java
50aabd
--- a/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 01 16:15:54 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11KeyGenerator.java	Fri Sep 08 11:09:23 2017 -0700
50aabd
@@ -178,8 +178,9 @@
50aabd
             byte[] pwbytes=null;
50aabd
             try {
50aabd
                 pwbytes = charToByte.convert( kgp.getPassword().getChars() );
50aabd
-                return generatePBE(token, algorithm, pwbytes,
50aabd
-                    kgp.getSalt(), kgp.getIterations());
50aabd
+                return generatePBE(
50aabd
+                    token, algorithm, kgp.getEncryptionAlgorithm(),
50aabd
+                    pwbytes, kgp.getSalt(), kgp.getIterations());
50aabd
             } finally {
50aabd
                 if( pwbytes!=null ) {
50aabd
                     Password.wipeBytes(pwbytes);
50aabd
@@ -296,7 +297,9 @@
50aabd
      *  be null.
50aabd
      */
50aabd
     private static native SymmetricKey
50aabd
-    generatePBE(PK11Token token, KeyGenAlgorithm algorithm, byte[] pass,
50aabd
-        byte[] salt, int iterationCount) throws TokenException;
50aabd
+    generatePBE(
50aabd
+        PK11Token token, KeyGenAlgorithm algorithm, EncryptionAlgorithm encAlg,
50aabd
+        byte[] pass, byte[] salt, int iterationCount)
50aabd
+        throws TokenException;
50aabd
 
50aabd
 }
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504894529 25200
50aabd
#      Fri Sep 08 11:15:29 2017 -0700
50aabd
# Node ID bada1409d2bb67cd92c3b7c292b8bb4ae6388513
50aabd
# Parent  3629b598a9ce73e83c7896407e3ca820f6383750
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch jss-ftweedal-0007-Support-the-CKK_GENERIC_SECRET-symmetric-key-type.patch
50aabd
Subject: Support the CKK_GENERIC_SECRET symmetric key type
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
Content-Type: text/plain
50aabd
found patch at byte 873
50aabd
message:
50aabd
Support the CKK_GENERIC_SECRET symmetric key type
50aabd
The NSS PBKDF2 generation produces a key with the CKK_GENERIC_SECRET
50aabd
key type.  The underlying PKCS #11 object *does* record the intended
50aabd
encryption algorithm that was specified when generating the key via
50aabd
PK11_PBEKeyGen, but this information is not exposed via the PKCS #11
50aabd
interface.  When initialising a cipher, JSS checks the key type
50aabd
against the encryption algorithm and fails if they do not match,
50aabd
which is always the case with PBKDF2-derived keys.
50aabd
50aabd
To work around this problem, properly record the key type for
50aabd
CKK_GENERIC_SECRET keys, and update the cipher initialisation key
50aabd
type check to always accept such keys.
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/KeyType.java
50aabd
--- a/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:09:23 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/KeyType.java	Fri Sep 08 11:15:29 2017 -0700
50aabd
@@ -242,4 +242,7 @@
50aabd
                             "SHA1_HMAC"
50aabd
                         );
50aabd
 
50aabd
+    static public final KeyType GENERIC_SECRET =
50aabd
+        new KeyType(new Algorithm[] { }, "GENERIC_SECRET");
50aabd
+
50aabd
 }
50aabd
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11Cipher.java
50aabd
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:09:23 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:15:29 2017 -0700
50aabd
@@ -243,8 +243,11 @@
50aabd
         }
50aabd
 
50aabd
         try {
50aabd
-            if( ((PK11SymKey)key).getKeyType() !=
50aabd
-                    KeyType.getKeyTypeFromAlgorithm(algorithm) ) {
50aabd
+            KeyType keyType = ((PK11SymKey) key).getKeyType();
50aabd
+            if (
50aabd
+                keyType != KeyType.GENERIC_SECRET
50aabd
+                && keyType != KeyType.getKeyTypeFromAlgorithm(algorithm)
50aabd
+            ) {
50aabd
                 throw new InvalidKeyException("Key is not the right type for"+
50aabd
                     " this algorithm: " + ((PK11SymKey)key).getKeyType() + ":" + KeyType.getKeyTypeFromAlgorithm(algorithm) +";");
50aabd
             }
50aabd
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/pkcs11/PK11SymKey.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:09:23 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11SymKey.c	Fri Sep 08 11:15:29 2017 -0700
50aabd
@@ -305,6 +305,9 @@
50aabd
           case CKK_DES2:
50aabd
              typeFieldName = DES3_KEYTYPE_FIELD;
50aabd
              break;
50aabd
+          case CKK_GENERIC_SECRET:
50aabd
+             typeFieldName = GENERIC_SECRET_KEYTYPE_FIELD;
50aabd
+             break;
50aabd
           default:
50aabd
             PR_ASSERT(PR_FALSE);
50aabd
             typeFieldName = DES_KEYTYPE_FIELD;
50aabd
diff -r 3629b598a9ce -r bada1409d2bb org/mozilla/jss/util/java_ids.h
50aabd
--- a/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:09:23 2017 -0700
50aabd
+++ b/org/mozilla/jss/util/java_ids.h	Fri Sep 08 11:15:29 2017 -0700
50aabd
@@ -87,6 +87,7 @@
50aabd
 #define RC2_KEYTYPE_FIELD "RC2"
50aabd
 #define SHA1_HMAC_KEYTYPE_FIELD "SHA1_HMAC"
50aabd
 #define AES_KEYTYPE_FIELD "AES"
50aabd
+#define GENERIC_SECRET_KEYTYPE_FIELD "GENERIC_SECRET"
50aabd
 
50aabd
 /*
50aabd
  * NativeProxy
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504894882 25200
50aabd
#      Fri Sep 08 11:21:22 2017 -0700
50aabd
# Node ID 890216599f21df4c6d07815604aaac526823a892
50aabd
# Parent  bada1409d2bb67cd92c3b7c292b8bb4ae6388513
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch jss-ftweedal-0008-PK11Cipher-improve-error-reporting.patch
50aabd
Subject: PK11Cipher: improve error reporting
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
message:
50aabd
PK11Cipher: improve error reporting
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r bada1409d2bb -r 890216599f21 org/mozilla/jss/pkcs11/PK11Cipher.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:15:29 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:21:22 2017 -0700
50aabd
@@ -152,7 +152,9 @@
50aabd
     /* do the operation */
50aabd
     if( PK11_CipherOp(context, outbuf, (int*)&outlen, outlen,
50aabd
             (unsigned char*)inbuf, inlen) != SECSuccess) {
50aabd
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher Operation failed");
50aabd
+        JSS_throwMsgPrErrArg(
50aabd
+            env, TOKEN_EXCEPTION, "Cipher context update failed",
50aabd
+            PR_GetError());
50aabd
         goto finish;
50aabd
     }
50aabd
     PR_ASSERT(outlen >= 0);
50aabd
@@ -209,7 +211,9 @@
50aabd
     /* perform the finalization */
50aabd
     status = PK11_DigestFinal(context, outBuf, &newOutLen, outLen);
50aabd
     if( (status != SECSuccess) ) {
50aabd
-        JSS_throwMsg(env, TOKEN_EXCEPTION, "Cipher operation failed on token");
50aabd
+        JSS_throwMsgPrErrArg(
50aabd
+            env, TOKEN_EXCEPTION, "Cipher context finalization failed",
50aabd
+            PR_GetError());
50aabd
         goto finish;
50aabd
     }
50aabd
 
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504895552 25200
50aabd
#      Fri Sep 08 11:32:32 2017 -0700
50aabd
# Node ID d39e9b373798ea9d6ae7f35089b07143845b210e
50aabd
# Parent  890216599f21df4c6d07815604aaac526823a892
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch jss-ftweedal-0009-Update-AES-CBC-PAD-cipher-definitions.patch
50aabd
Subject: Update AES-CBC-PAD cipher definitions
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
message:
50aabd
Update AES-CBC-PAD cipher definitions
50aabd
The AES_{128,192,256}_CBC_PAD EncryptionAlgorithm definitions declare
50aabd
the correct PKCS #11 cipher mechanism and padding, but do not declare
50aabd
the relevant OIDs.  They are also unusable as target algorithms in
50aabd
PBE key generation because they declare a PK11_MECH instead of a
50aabd
SEC_OID_TAG.
50aabd
50aabd
Update these algorithms definitions to declare a SEC_OID_TAG instead
50aabd
of a PK11_MECH (JSS_getOidTagFromAlg() will still return the correct
50aabd
mechanism) and declare the associated OIDs.
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r 890216599f21 -r d39e9b373798 org/mozilla/jss/crypto/EncryptionAlgorithm.java
50aabd
--- a/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:21:22 2017 -0700
50aabd
+++ b/org/mozilla/jss/crypto/EncryptionAlgorithm.java	Fri Sep 08 11:32:32 2017 -0700
50aabd
@@ -359,8 +359,10 @@
50aabd
         AES_ROOT_OID.subBranch(2), 128);
50aabd
 
50aabd
     public static final EncryptionAlgorithm
50aabd
-    AES_128_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
50aabd
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 128); // no oid
50aabd
+    AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC,
50aabd
+        Alg.AES, Mode.CBC,
50aabd
+        Padding.PKCS5, IVParameterSpecClasses, 16,
50aabd
+        AES_ROOT_OID.subBranch(2), 128);
50aabd
     
50aabd
     public static final EncryptionAlgorithm
50aabd
     AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB,
50aabd
@@ -374,8 +376,10 @@
50aabd
         AES_ROOT_OID.subBranch(22), 192);
50aabd
     
50aabd
     public static final EncryptionAlgorithm
50aabd
-    AES_192_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC,
50aabd
-        Padding.PKCS5, IVParameterSpecClasses, 16, null, 192); // no oid
50aabd
+    AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC,
50aabd
+        Alg.AES, Mode.CBC,
50aabd
+        Padding.PKCS5, IVParameterSpecClasses, 16,
50aabd
+        AES_ROOT_OID.subBranch(22), 192);
50aabd
 
50aabd
     public static final EncryptionAlgorithm
50aabd
     AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB,
50aabd
@@ -393,6 +397,9 @@
50aabd
         Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid
50aabd
     
50aabd
     public static final EncryptionAlgorithm
50aabd
-    AES_256_CBC_PAD = AES_CBC_PAD;
50aabd
+    AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC,
50aabd
+        Alg.AES, Mode.CBC,
50aabd
+        Padding.PKCS5, IVParameterSpecClasses, 16,
50aabd
+        AES_ROOT_OID.subBranch(42), 256);
50aabd
     
50aabd
 }
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504896621 25200
50aabd
#      Fri Sep 08 11:50:21 2017 -0700
50aabd
# Node ID 0b8a6e84b6c736743f2184b2b858fda6be740544
50aabd
# Parent  d39e9b373798ea9d6ae7f35089b07143845b210e
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch jss-ftweedal-0010-PK11Cipher-use-pad-mechanism-for-algorithms-that-use.patch
50aabd
Subject: PK11Cipher: use pad mechanism for algorithms that use padding
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
message:
50aabd
PK11Cipher: use pad mechanism for algorithms that use padding
50aabd
The PK11Cipher implementation, when initialising a cipher context,
50aabd
uses JSS_getPK11MechFromAlg() to retrieve the PKCS #11 mechanism to
50aabd
use.  When a JSS EncryptionAlgorithm uses a SEC_OID_TAG, this will
50aabd
return the non-padded mechanism.  Then, if the size of the data is
50aabd
not a multiple of the cipher block size, a padding error occurs.
50aabd
50aabd
When the EncryptionAlgorithm indicates that padding is to be used,
50aabd
call PK11_GetPadMechanism() on the result of JSS_getPK11MechFromAlg()
50aabd
to get the padding variant of the mechanism.
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:32:32 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.c	Fri Sep 08 11:50:21 2017 -0700
50aabd
@@ -24,16 +24,16 @@
50aabd
 JNIEXPORT jobject JNICALL
50aabd
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext
50aabd
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
50aabd
-        jobject algObj, jbyteArray ivBA)
50aabd
+        jobject algObj, jbyteArray ivBA, jboolean padded)
50aabd
 {
50aabd
     return Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
50aabd
-        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0);
50aabd
+        ( env, clazz, encrypt, keyObj, algObj, ivBA, 0, padded);
50aabd
 }
50aabd
 
50aabd
 JNIEXPORT jobject JNICALL
50aabd
 Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits
50aabd
     (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj,
50aabd
-        jobject algObj, jbyteArray ivBA, jint keyBits)
50aabd
+        jobject algObj, jbyteArray ivBA, jint keyBits, jboolean padded)
50aabd
 {
50aabd
     CK_MECHANISM_TYPE mech;
50aabd
     PK11SymKey *key=NULL;
50aabd
@@ -53,6 +53,9 @@
50aabd
         goto finish;
50aabd
     }
50aabd
 
50aabd
+    if (padded)
50aabd
+        mech = PK11_GetPadMechanism(mech);
50aabd
+
50aabd
     /* get operation type */
50aabd
     if( encrypt ) {
50aabd
         op = CKA_ENCRYPT;
50aabd
diff -r d39e9b373798 -r 0b8a6e84b6c7 org/mozilla/jss/pkcs11/PK11Cipher.java
50aabd
--- a/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:32:32 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11Cipher.java	Fri Sep 08 11:50:21 2017 -0700
50aabd
@@ -90,10 +90,13 @@
50aabd
         state = ENCRYPT;
50aabd
 
50aabd
         if( parameters instanceof RC2ParameterSpec ) {
50aabd
-            contextProxy = initContextWithKeyBits( true, key, algorithm, IV,
50aabd
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
50aabd
+            contextProxy = initContextWithKeyBits(
50aabd
+                true, key, algorithm, IV,
50aabd
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
50aabd
+                algorithm.isPadded());
50aabd
         } else {
50aabd
-            contextProxy = initContext( true, key, algorithm, IV );
50aabd
+            contextProxy = initContext(
50aabd
+                true, key, algorithm, IV, algorithm.isPadded());
50aabd
         }
50aabd
     }
50aabd
 
50aabd
@@ -112,10 +115,13 @@
50aabd
         state = DECRYPT;
50aabd
 
50aabd
         if( parameters instanceof RC2ParameterSpec ) {
50aabd
-            contextProxy = initContextWithKeyBits(false, key, algorithm, IV,
50aabd
-                ((RC2ParameterSpec)parameters).getEffectiveKeyBits() );
50aabd
+            contextProxy = initContextWithKeyBits(
50aabd
+                false, key, algorithm, IV,
50aabd
+                ((RC2ParameterSpec)parameters).getEffectiveKeyBits(),
50aabd
+                algorithm.isPadded());
50aabd
         } else {
50aabd
-            contextProxy = initContext(false, key, algorithm, IV);
50aabd
+            contextProxy = initContext(
50aabd
+                false, key, algorithm, IV, algorithm.isPadded());
50aabd
         }
50aabd
     }
50aabd
 
50aabd
@@ -182,13 +188,13 @@
50aabd
 
50aabd
     private static native CipherContextProxy
50aabd
     initContext(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg,
50aabd
-                 byte[] IV)
50aabd
+                 byte[] IV, boolean padded)
50aabd
         throws TokenException;
50aabd
 
50aabd
     // This version accepts the number of effective key bits for RC2 CBC.
50aabd
     private static native CipherContextProxy
50aabd
     initContextWithKeyBits(boolean encrypt, SymmetricKey key,
50aabd
-                EncryptionAlgorithm alg, byte[] IV, int keyBits)
50aabd
+                EncryptionAlgorithm alg, byte[] IV, int keyBits, boolean padded)
50aabd
         throws TokenException;
50aabd
 
50aabd
     private static native byte[]
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504896816 25200
50aabd
#      Fri Sep 08 11:53:36 2017 -0700
50aabd
# Node ID b3b653faef8475ae03c670766429fd4dfab37a5e
50aabd
# Parent  0b8a6e84b6c736743f2184b2b858fda6be740544
50aabd
bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch jss-ftweedal-0012-2-Add-method-EncryptedPrivateKeyInfo.createPBES2.patch
50aabd
Subject: Add method EncryptedPrivateKeyInfo.createPBES2
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
Content-Type: text/plain
50aabd
found patch at byte 404
50aabd
message:
50aabd
Add method EncryptedPrivateKeyInfo.createPBES2
50aabd
The createPBE method does not support PBES2 (it is necessary to know
50aabd
the desired encrypted algorithm to derive the key and build the
50aabd
parameters data).  Add the createPBES2 method, which uses PBKDF2 to
50aabd
derive the symmetric key and allows the caller to specify the
50aabd
encryption algorithm.
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r 0b8a6e84b6c7 -r b3b653faef84 org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java
50aabd
--- a/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:50:21 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java	Fri Sep 08 11:53:36 2017 -0700
50aabd
@@ -155,6 +155,100 @@
50aabd
 
50aabd
 
50aabd
     /**
50aabd
+     * Export a private key in PBES2 format, using a random PBKDF2 salt.
50aabd
+     *
50aabd
+     * Token must support the CKM_PKCS5_PBKD2 mechanism.
50aabd
+     *
50aabd
+     * @param saltLen Length of salt in bytes (default: 16)
50aabd
+     * @param kdfIterations PBKDF2 iterations (default: 2000)
50aabd
+     * @param encAlg The symmetric encryption algorithm for enciphering the
50aabd
+     *               private key.  Determines the size of derived key.
50aabd
+     * @param pwd Password
50aabd
+     * @param charToByteConverter The mechanism for converting the characters
50aabd
+     *      in the password into bytes.  If null, the default mechanism
50aabd
+     *      will be used, which is UTF8.
50aabd
+     * @param privateKeyInfo The encoded PrivateKeyInfo to be encrypted and
50aabd
+     *                       stored in the EncryptedContentInfo.
50aabd
+     */
50aabd
+    public static EncryptedPrivateKeyInfo createPBES2(
50aabd
+            int saltLen,
50aabd
+            int kdfIterations,
50aabd
+            EncryptionAlgorithm encAlg,
50aabd
+            Password pwd,
50aabd
+            KeyGenerator.CharToByteConverter charToByteConverter,
50aabd
+            PrivateKeyInfo privateKeyInfo)
50aabd
+        throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
50aabd
+        InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
50aabd
+        CharConversionException
50aabd
+    {
50aabd
+        if (encAlg == null)
50aabd
+            throw new IllegalArgumentException("encAlg cannot be null");
50aabd
+        if (pwd == null)
50aabd
+            throw new IllegalArgumentException("pwd cannot be null");
50aabd
+        if (privateKeyInfo == null)
50aabd
+            throw new IllegalArgumentException("privateKeyInfo cannot be null");
50aabd
+
50aabd
+        if (kdfIterations < 1)
50aabd
+            kdfIterations = 2000;
50aabd
+        if (saltLen < 1)
50aabd
+            saltLen = 16;
50aabd
+
50aabd
+        try {
50aabd
+            // generate random PBKDF2 salt
50aabd
+            SecureRandom random = new SecureRandom();
50aabd
+            byte salt[] = new byte[saltLen];
50aabd
+            random.nextBytes(salt);
50aabd
+
50aabd
+            // derive symmetric key from passphrase using PBKDF2
50aabd
+            CryptoManager cm = CryptoManager.getInstance();
50aabd
+            CryptoToken token = cm.getInternalCryptoToken();
50aabd
+            KeyGenerator kg = token.getKeyGenerator(
50aabd
+                PBEAlgorithm.PBE_PKCS5_PBKDF2);
50aabd
+            PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
50aabd
+                pwd.getChars(), salt, kdfIterations, encAlg);
50aabd
+            if (charToByteConverter != null)
50aabd
+                kg.setCharToByteConverter(charToByteConverter);
50aabd
+            kg.initialize(pbekgParams);
50aabd
+            SymmetricKey sk = kg.generate();
50aabd
+
50aabd
+            // encrypt PrivateKeyInfo
50aabd
+            byte iv[] = new byte[encAlg.getBlockSize()];
50aabd
+            random.nextBytes(iv);
50aabd
+            Cipher cipher = token.getCipherContext(encAlg);
50aabd
+            cipher.initEncrypt(sk, new IVParameterSpec(iv));
50aabd
+            byte[] encData = cipher.doFinal(ASN1Util.encode(privateKeyInfo));
50aabd
+
50aabd
+            // construct KDF AlgorithmIdentifier
50aabd
+            SEQUENCE paramsKdf = new SEQUENCE();
50aabd
+            paramsKdf.addElement(new OCTET_STRING(salt));
50aabd
+            paramsKdf.addElement(new INTEGER((long) kdfIterations));
50aabd
+            paramsKdf.addElement(new INTEGER((long) sk.getLength()));
50aabd
+            AlgorithmIdentifier algIdKdf = new AlgorithmIdentifier(
50aabd
+                PBEAlgorithm.PBE_PKCS5_PBKDF2.toOID(), paramsKdf);
50aabd
+
50aabd
+            // construct encryption AlgorithmIdentifier
50aabd
+            AlgorithmIdentifier algIdEnc = new AlgorithmIdentifier(
50aabd
+                encAlg.toOID(), new OCTET_STRING(iv));
50aabd
+
50aabd
+            // construct "composite" PBES2 AlgorithmIdentifier
50aabd
+            SEQUENCE paramsPBES2 = new SEQUENCE();
50aabd
+            paramsPBES2.addElement(algIdKdf);
50aabd
+            paramsPBES2.addElement(algIdEnc);
50aabd
+            AlgorithmIdentifier algIdPBES2 = new AlgorithmIdentifier(
50aabd
+                PBEAlgorithm.PBE_PKCS5_PBES2.toOID(), paramsPBES2);
50aabd
+
50aabd
+            // construct EncryptedPrivateKeyInfo
50aabd
+            return new EncryptedPrivateKeyInfo(algIdPBES2, new OCTET_STRING(encData));
50aabd
+        } catch (IllegalBlockSizeException e) {
50aabd
+            Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo.createPBES2");
50aabd
+        } catch (BadPaddingException e) {
50aabd
+            Assert.notReached("BadPaddingException in EncryptedContentInfo.createPBES2");
50aabd
+        }
50aabd
+        return null; // unreachable
50aabd
+    }
50aabd
+
50aabd
+
50aabd
+    /**
50aabd
      * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted
50aabd
      * with a password-based key- 
50aabd
      *       with wrapping/unwrapping happening on token.
50aabd
# HG changeset patch
50aabd
# User Fraser Tweedale<ftweedale@redhat.com>
50aabd
# Date 1504896964 25200
50aabd
#      Fri Sep 08 11:56:04 2017 -0700
50aabd
# Node ID 87dca07f7529463398734d1279bcfd7023a43d4c
50aabd
# Parent  b3b653faef8475ae03c670766429fd4dfab37a5e
50aabd
Bug 1370778 PBE and padded block cipher enhancements and fixes -
50aabd
patch  jss-ftweedal-0013-Improve-error-reporting.patch
50aabd
Subject: Improve error reporting
50aabd
From: Fraser Tweedale <ftweedal@redhat.com>
50aabd
Content-Type: text/plain
50aabd
found patch at byte 157
50aabd
message:
50aabd
Improve error reporting
50aabd
50aabd
cfu for ftweedal
50aabd
50aabd
diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11KeyWrapper.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:53:36 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.c	Fri Sep 08 11:56:04 2017 -0700
50aabd
@@ -251,9 +251,7 @@
50aabd
     status = PK11_WrapPrivKey(slot, wrapping, toBeWrapped, mech, param,
50aabd
                 &wrapped, NULL /* wincx */ );
50aabd
     if(status != SECSuccess) {
50aabd
-        char err[256] = {0};
50aabd
-        PR_snprintf(err, 256, "Wrapping operation failed on token:%d", PR_GetError());
50aabd
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
50aabd
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Wrapping operation failed on token");
50aabd
         goto finish;
50aabd
     }
50aabd
     PR_ASSERT(wrapped.len>0 && wrapped.data!=NULL);
50aabd
@@ -450,8 +448,8 @@
50aabd
                 attribs, numAttribs, NULL /*wincx*/);
50aabd
     if( privk == NULL ) {
50aabd
         char err[256] = {0};
50aabd
-        PR_snprintf(err, 256, "Key Unwrap failed on token:error=%d, keyType=%d", PR_GetError(), keyType);
50aabd
-        JSS_throwMsg(env, TOKEN_EXCEPTION, err);
50aabd
+        PR_snprintf(err, 256, "Key Unwrap failed on token; keyType=%d", keyType);
50aabd
+        JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, err);
50aabd
         goto finish;
50aabd
     }
50aabd
                 
50aabd
diff -r b3b653faef84 -r 87dca07f7529 org/mozilla/jss/pkcs11/PK11Store.c
50aabd
--- a/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:53:36 2017 -0700
50aabd
+++ b/org/mozilla/jss/pkcs11/PK11Store.c	Fri Sep 08 11:56:04 2017 -0700
50aabd
@@ -734,7 +734,7 @@
50aabd
         PR_TRUE /* isperm */, PR_TRUE /* isprivate */,
50aabd
         pubKey->keyType, keyUsage, NULL /* wincx */);
50aabd
     if (result != SECSuccess) {
50aabd
-        JSS_throwMsg(
50aabd
+        JSS_throwMsgPrErr(
50aabd
             env, TOKEN_EXCEPTION,
50aabd
             "Failed to import EncryptedPrivateKeyInfo to token");
50aabd
         goto finish;