Restore some old decrypt functionality

Some of the convoluted convert_hex_ascii_to_key code is needed to
properly decrypt CM 12.1 patterns where grid size is larger than
3x3.

Change-Id: I497e17980046c60d2c69ba56e4b83c8b64b0b80e
diff --git a/crypto/lollipop/cryptfs.c b/crypto/lollipop/cryptfs.c
index fe075c4..56f10b9 100644
--- a/crypto/lollipop/cryptfs.c
+++ b/crypto/lollipop/cryptfs.c
@@ -842,6 +842,49 @@
   return rc;
 }
 
+static int hexdigit (char c)
+{
+    if (c >= '0' && c <= '9') return c - '0';
+    c = tolower(c);
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    return -1;
+}
+
+static unsigned char* convert_hex_ascii_to_key(const char* master_key_ascii,
+                                               unsigned int* out_keysize)
+{
+    unsigned int i;
+    *out_keysize = 0;
+
+    size_t size = strlen (master_key_ascii);
+    if (size % 2) {
+        printf("Trying to convert ascii string of odd length\n");
+        return NULL;
+    }
+
+    unsigned char* master_key = (unsigned char*) malloc(size / 2);
+    if (master_key == 0) {
+        printf("Cannot allocate\n");
+        return NULL;
+    }
+
+    for (i = 0; i < size; i += 2) {
+        int high_nibble = hexdigit (master_key_ascii[i]);
+        int low_nibble = hexdigit (master_key_ascii[i + 1]);
+
+        if(high_nibble < 0 || low_nibble < 0) {
+            printf("Invalid hex string\n");
+            free (master_key);
+            return NULL;
+        }
+
+        master_key[*out_keysize] = high_nibble * 16 + low_nibble;
+        (*out_keysize)++;
+    }
+
+    return master_key;
+}
+
 /* Convert a binary key of specified length into an ascii hex string equivalent,
  * without the leading 0x and with null termination
  */
@@ -1114,9 +1157,14 @@
     printf("Using pbkdf2 for cryptfs KDF\n");
 
     /* Turn the password into a key and IV that can decrypt the master key */
-    PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN,
+    unsigned int keysize;
+    char* master_key = (char*)convert_hex_ascii_to_key(passwd, &keysize);
+    if (!master_key) return -1;
+    PKCS5_PBKDF2_HMAC_SHA1(master_key, keysize, salt, SALT_LEN,
                            HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey);
 
+    memset(master_key, 0, keysize);
+    free (master_key);
     return 0;
 }
 
@@ -1132,9 +1180,14 @@
     int p = 1 << ftr->p_factor;
 
     /* Turn the password into a key and IV that can decrypt the master key */
-    crypto_scrypt((const uint8_t *)passwd, strlen(passwd), salt, SALT_LEN,
-            N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES);
+    unsigned int keysize;
+    unsigned char* master_key = convert_hex_ascii_to_key(passwd, &keysize);
+    if (!master_key) return -1;
+    crypto_scrypt(master_key, keysize, salt, SALT_LEN, N, r, p, ikey,
+            KEY_LEN_BYTES + IV_LEN_BYTES);
 
+    memset(master_key, 0, keysize);
+    free (master_key);
     return 0;
 }
 
@@ -1153,8 +1206,16 @@
     int r = 1 << ftr->r_factor;
     int p = 1 << ftr->p_factor;
 
-    rc = crypto_scrypt((const uint8_t *)passwd, strlen(passwd), salt, SALT_LEN,
+    unsigned char* master_key = convert_hex_ascii_to_key(passwd, &key_size);
+    if (!master_key) {
+        printf("Failed to convert passwd from hex\n");
+        return -1;
+    }
+
+    rc = crypto_scrypt(master_key, key_size, salt, SALT_LEN,
                        N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES);
+    memset(master_key, 0, key_size);
+    free(master_key);
 
     if (rc) {
         printf("scrypt failed\n");