Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/spongycastle/crypto/generators/BaseKDFBytesGenerator.java')
-rw-r--r--core/src/main/java/org/spongycastle/crypto/generators/BaseKDFBytesGenerator.java143
1 files changed, 143 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/crypto/generators/BaseKDFBytesGenerator.java b/core/src/main/java/org/spongycastle/crypto/generators/BaseKDFBytesGenerator.java
new file mode 100644
index 00000000..0d1577cd
--- /dev/null
+++ b/core/src/main/java/org/spongycastle/crypto/generators/BaseKDFBytesGenerator.java
@@ -0,0 +1,143 @@
+package org.spongycastle.crypto.generators;
+
+import org.spongycastle.crypto.DataLengthException;
+import org.spongycastle.crypto.DerivationParameters;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.DigestDerivationFunction;
+import org.spongycastle.crypto.params.ISO18033KDFParameters;
+import org.spongycastle.crypto.params.KDFParameters;
+import org.spongycastle.util.Pack;
+
+/**
+ * Basic KDF generator for derived keys and ivs as defined by IEEE P1363a/ISO
+ * 18033 <br>
+ * This implementation is based on ISO 18033/P1363a.
+ */
+public class BaseKDFBytesGenerator
+ implements DigestDerivationFunction
+{
+ private int counterStart;
+ private Digest digest;
+ private byte[] shared;
+ private byte[] iv;
+
+ /**
+ * Construct a KDF Parameters generator.
+ * <p>
+ *
+ * @param counterStart
+ * value of counter.
+ * @param digest
+ * the digest to be used as the source of derived keys.
+ */
+ protected BaseKDFBytesGenerator(int counterStart, Digest digest)
+ {
+ this.counterStart = counterStart;
+ this.digest = digest;
+ }
+
+ public void init(DerivationParameters param)
+ {
+ if (param instanceof KDFParameters)
+ {
+ KDFParameters p = (KDFParameters)param;
+
+ shared = p.getSharedSecret();
+ iv = p.getIV();
+ }
+ else if (param instanceof ISO18033KDFParameters)
+ {
+ ISO18033KDFParameters p = (ISO18033KDFParameters)param;
+
+ shared = p.getSeed();
+ iv = null;
+ }
+ else
+ {
+ throw new IllegalArgumentException("KDF parameters required for KDF2Generator");
+ }
+ }
+
+ /**
+ * return the underlying digest.
+ */
+ public Digest getDigest()
+ {
+ return digest;
+ }
+
+ /**
+ * fill len bytes of the output buffer with bytes generated from the
+ * derivation function.
+ *
+ * @throws IllegalArgumentException
+ * if the size of the request will cause an overflow.
+ * @throws DataLengthException
+ * if the out buffer is too small.
+ */
+ public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException,
+ IllegalArgumentException
+ {
+ if ((out.length - len) < outOff)
+ {
+ throw new DataLengthException("output buffer too small");
+ }
+
+ long oBytes = len;
+ int outLen = digest.getDigestSize();
+
+ //
+ // this is at odds with the standard implementation, the
+ // maximum value should be hBits * (2^32 - 1) where hBits
+ // is the digest output size in bits. We can't have an
+ // array with a long index at the moment...
+ //
+ if (oBytes > ((2L << 32) - 1))
+ {
+ throw new IllegalArgumentException("Output length too large");
+ }
+
+ int cThreshold = (int)((oBytes + outLen - 1) / outLen);
+
+ byte[] dig = new byte[digest.getDigestSize()];
+
+ byte[] C = new byte[4];
+ Pack.intToBigEndian(counterStart, C, 0);
+
+ int counterBase = counterStart & ~0xFF;
+
+ for (int i = 0; i < cThreshold; i++)
+ {
+ digest.update(shared, 0, shared.length);
+ digest.update(C, 0, C.length);
+
+ if (iv != null)
+ {
+ digest.update(iv, 0, iv.length);
+ }
+
+ digest.doFinal(dig, 0);
+
+ if (len > outLen)
+ {
+ System.arraycopy(dig, 0, out, outOff, outLen);
+ outOff += outLen;
+ len -= outLen;
+ }
+ else
+ {
+ System.arraycopy(dig, 0, out, outOff, len);
+ }
+
+ if (++C[3] == 0)
+ {
+ counterBase += 0x100;
+ Pack.intToBigEndian(counterBase, C, 0);
+ }
+ }
+
+ digest.reset();
+
+ return (int)oBytes;
+ }
+}