diff options
author | David Hook <dgh@cryptoworkshop.com> | 2014-06-16 04:09:53 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2014-06-16 04:09:53 +0400 |
commit | f74732c1d2308def554578ce79ce16e19cb221f8 (patch) | |
tree | f799d6a0027bb522690f16cf80ef95785dd2b40a /core/src/main/java/org/bouncycastle/crypto | |
parent | 6bf59b77d8e54b5fee8ce06fec2439ab908d5bc7 (diff) | |
parent | 88b7a3c24626226e9954f59e5f615f39b373cba2 (diff) |
Merge branch 'master' of https://github.com/MauriceAarts/bc-java into MauriceAarts-master
Diffstat (limited to 'core/src/main/java/org/bouncycastle/crypto')
-rw-r--r-- | core/src/main/java/org/bouncycastle/crypto/generators/KDFCounterBytesGenerator.java | 29 | ||||
-rw-r--r-- | core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java | 62 |
2 files changed, 82 insertions, 9 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/KDFCounterBytesGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/KDFCounterBytesGenerator.java index 306530ec..7611dd8b 100644 --- a/core/src/main/java/org/bouncycastle/crypto/generators/KDFCounterBytesGenerator.java +++ b/core/src/main/java/org/bouncycastle/crypto/generators/KDFCounterBytesGenerator.java @@ -11,6 +11,26 @@ import org.bouncycastle.crypto.params.KeyParameter; /** * This KDF has been defined by the publicly available NIST SP 800-108 specification. + * NIST SP800-108 allows for alternative orderings of the input fields, meaning that the input can be formated in multiple ways. + * There are 3 supported formats: - Below [i]_2 is a counter of r-bits length concatenated to the fixedInputData. + * 1: K(i) := PRF( KI, [i]_2 || Label || 0x00 || Context || [L]_2 ) with the counter at the very beginning of the fixedInputData (The default implementation has this format) + * 2: K(i) := PRF( KI, Label || 0x00 || Context || [L]_2 || [i]_2 ) with the counter at the very end of the fixedInputData + * 3a: K(i) := PRF( KI, Label || 0x00 || [i]_2 || Context || [L]_2 ) OR: + * 3b: K(i) := PRF( KI, Label || 0x00 || [i]_2 || [L]_2 || Context ) OR: + * 3c: K(i) := PRF( KI, Label || [i]_2 || 0x00 || Context || [L]_2 ) etc... with the counter somewhere in the 'middle' of the fixedInputData. + * + * This function must be called with the following KDFCounterParameters(): + * - KI + * - The part of the fixedInputData that comes BEFORE the counter OR null + * - the part of the fixedInputData that comes AFTER the counter OR null + * - the length of the counter in bits (not bytes) + * + * Resulting function calls assuming an 8 bit counter. + * 1. KDFCounterParameters(ki, null, "Label || 0x00 || Context || [L]_2]", 8); + * 2. KDFCounterParameters(ki, "Label || 0x00 || Context || [L]_2]", null, 8); + * 3a. KDFCounterParameters(ki, "Label || 0x00", "Context || [L]_2]", 8); + * 3b. KDFCounterParameters(ki, "Label || 0x00", "[L]_2] || Context", 8); + * 3c. KDFCounterParameters(ki, "Label", "0x00 || Context || [L]_2]", 8); */ public class KDFCounterBytesGenerator implements MacDerivationFunction @@ -27,7 +47,8 @@ public class KDFCounterBytesGenerator private final int h; // fields set by init - private byte[] fixedInputData; + private byte[] fixedInputData_beforeCtr; + private byte[] fixedInputData_afterCtr; private int maxSizeExcl; // ios is i defined as an octet string (the binary representation) private byte[] ios; @@ -61,7 +82,8 @@ public class KDFCounterBytesGenerator // --- set arguments --- - this.fixedInputData = kdfParams.getFixedInputData(); + this.fixedInputData_beforeCtr = kdfParams.getFixedInputData_beforeCtr(); + this.fixedInputData_afterCtr = kdfParams.getFixedInputData_afterCtr(); int r = kdfParams.getR(); this.ios = new byte[r / 8]; @@ -145,8 +167,9 @@ public class KDFCounterBytesGenerator // special case for K(0): K(0) is empty, so no update + prf.update(fixedInputData_beforeCtr, 0, fixedInputData_beforeCtr.length); prf.update(ios, 0, ios.length); - prf.update(fixedInputData, 0, fixedInputData.length); + prf.update(fixedInputData_afterCtr, 0, fixedInputData_afterCtr.length); prf.doFinal(k, 0); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java b/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java index 0eb6cb70..2c5f55e4 100644 --- a/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java +++ b/core/src/main/java/org/bouncycastle/crypto/params/KDFCounterParameters.java @@ -8,24 +8,64 @@ public final class KDFCounterParameters { private final byte[] ki; - private final byte[] fixedInputData; + private final byte[] fixedInputData_beforeCtr; + private final byte[] fixedInputData_afterCtr; private final int r; + /** + * This KDF has been defined by the publicly available NIST SP 800-108 specification. + * NIST SP800-108 allows for alternative orderings of the input fields, meaning that the input can be formated in multiple ways. + * There are 3 supported formats: - Below [i]_2 is a counter of r-bits length concatenated to the fixedInputData. + * 1: K(i) := PRF( KI, [i]_2 || Label || 0x00 || Context || [L]_2 ) with the counter at the very beginning of the fixedInputData (The default implementation has this format) + * 2: K(i) := PRF( KI, Label || 0x00 || Context || [L]_2 || [i]_2 ) with the counter at the very end of the fixedInputData + * 3a: K(i) := PRF( KI, Label || 0x00 || [i]_2 || Context || [L]_2 ) OR: + * 3b: K(i) := PRF( KI, Label || 0x00 || [i]_2 || [L]_2 || Context ) OR: + * 3c: K(i) := PRF( KI, Label || [i]_2 || 0x00 || Context || [L]_2 ) etc... with the counter somewhere in the 'middle' of the fixedInputData. + * + * This function must be called with the following KDFCounterParameters(): + * - KI + * - The part of the fixedInputData that comes BEFORE the counter OR null + * - the part of the fixedInputData that comes AFTER the counter OR null + * - the length of the counter in bits (not bytes) + * + * Resulting function calls assuming an 8 bit counter. + * 1. KDFCounterParameters(ki, null, "Label || 0x00 || Context || [L]_2]", 8); + * 2. KDFCounterParameters(ki, "Label || 0x00 || Context || [L]_2]", null, 8); + * 3a. KDFCounterParameters(ki, "Label || 0x00", "Context || [L]_2]", 8); + * 3b. KDFCounterParameters(ki, "Label || 0x00", "[L]_2] || Context", 8); + * 3c. KDFCounterParameters(ki, "Label", "0x00 || Context || [L]_2]", 8); + */ + public KDFCounterParameters(byte[] ki, byte[] fixedInputData, int r) { + //Retained for backwards compatibility + this(ki, null, fixedInputData, r); + } + + public KDFCounterParameters(byte[] ki, byte[] fixedInputData_beforeCtr, byte[] fixedInputData_afterCtr, int r) + { if (ki == null) { throw new IllegalArgumentException("A KDF requires Ki (a seed) as input"); } this.ki = Arrays.clone(ki); - if (fixedInputData == null) + if (fixedInputData_beforeCtr == null) { - this.fixedInputData = new byte[0]; + this.fixedInputData_beforeCtr = new byte[0]; } else { - this.fixedInputData = Arrays.clone(fixedInputData); + this.fixedInputData_beforeCtr = Arrays.clone(fixedInputData_beforeCtr); + } + + if (fixedInputData_afterCtr == null) + { + this.fixedInputData_afterCtr = new byte[0]; + } + else + { + this.fixedInputData_afterCtr = Arrays.clone(fixedInputData_afterCtr); } if (r != 8 && r != 16 && r != 24 && r != 32) @@ -34,7 +74,7 @@ public final class KDFCounterParameters } this.r = r; } - + public byte[] getKI() { return ki; @@ -42,9 +82,19 @@ public final class KDFCounterParameters public byte[] getFixedInputData() { - return Arrays.clone(fixedInputData); + //Retained for backwards compatibility + return Arrays.clone(fixedInputData_afterCtr); } + public byte[] getFixedInputData_beforeCtr() + { + return Arrays.clone(fixedInputData_beforeCtr); + } + + public byte[] getFixedInputData_afterCtr() + { + return Arrays.clone(fixedInputData_afterCtr); + } public int getR() { return r; |