mobile/android/base/sync/crypto/PBKDF2.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.sync.crypto;
michael@0 6
michael@0 7 import java.security.GeneralSecurityException;
michael@0 8 import java.util.Arrays;
michael@0 9
michael@0 10 import javax.crypto.Mac;
michael@0 11 import javax.crypto.ShortBufferException;
michael@0 12 import javax.crypto.spec.SecretKeySpec;
michael@0 13
michael@0 14 public class PBKDF2 {
michael@0 15 public static byte[] pbkdf2SHA256(byte[] password, byte[] salt, int c, int dkLen)
michael@0 16 throws GeneralSecurityException {
michael@0 17 final String algorithm = "HmacSHA256";
michael@0 18 SecretKeySpec keyspec = new SecretKeySpec(password, algorithm);
michael@0 19 Mac prf = Mac.getInstance(algorithm);
michael@0 20 prf.init(keyspec);
michael@0 21
michael@0 22 int hLen = prf.getMacLength();
michael@0 23
michael@0 24 byte U_r[] = new byte[hLen];
michael@0 25 byte U_i[] = new byte[salt.length + 4];
michael@0 26 byte scratch[] = new byte[hLen];
michael@0 27
michael@0 28 int l = Math.max(dkLen, hLen);
michael@0 29 int r = dkLen - (l - 1) * hLen;
michael@0 30 byte T[] = new byte[l * hLen];
michael@0 31 int ti_offset = 0;
michael@0 32 for (int i = 1; i <= l; i++) {
michael@0 33 Arrays.fill(U_r, (byte) 0);
michael@0 34 F(T, ti_offset, prf, salt, c, i, U_r, U_i, scratch);
michael@0 35 ti_offset += hLen;
michael@0 36 }
michael@0 37
michael@0 38 if (r < hLen) {
michael@0 39 // Incomplete last block.
michael@0 40 byte DK[] = new byte[dkLen];
michael@0 41 System.arraycopy(T, 0, DK, 0, dkLen);
michael@0 42 return DK;
michael@0 43 }
michael@0 44
michael@0 45 return T;
michael@0 46 }
michael@0 47
michael@0 48 private static void F(byte[] dest, int offset, Mac prf, byte[] S, int c, int blockIndex, byte U_r[], byte U_i[], byte[] scratch)
michael@0 49 throws ShortBufferException, IllegalStateException {
michael@0 50 final int hLen = prf.getMacLength();
michael@0 51
michael@0 52 // U0 = S || INT (i);
michael@0 53 System.arraycopy(S, 0, U_i, 0, S.length);
michael@0 54 INT(U_i, S.length, blockIndex);
michael@0 55
michael@0 56 for (int i = 0; i < c; i++) {
michael@0 57 prf.update(U_i);
michael@0 58 prf.doFinal(scratch, 0);
michael@0 59 U_i = scratch;
michael@0 60 xor(U_r, U_i);
michael@0 61 }
michael@0 62
michael@0 63 System.arraycopy(U_r, 0, dest, offset, hLen);
michael@0 64 }
michael@0 65
michael@0 66 private static void xor(byte[] dest, byte[] src) {
michael@0 67 for (int i = 0; i < dest.length; i++) {
michael@0 68 dest[i] ^= src[i];
michael@0 69 }
michael@0 70 }
michael@0 71
michael@0 72 private static void INT(byte[] dest, int offset, int i) {
michael@0 73 dest[offset + 0] = (byte) (i / (256 * 256 * 256));
michael@0 74 dest[offset + 1] = (byte) (i / (256 * 256));
michael@0 75 dest[offset + 2] = (byte) (i / (256));
michael@0 76 dest[offset + 3] = (byte) (i);
michael@0 77 }
michael@0 78 }

mercurial