org.bouncycastle.openpgp.operator.bc.RFC6637KDFCalculator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gwt-crypto Show documentation
Show all versions of gwt-crypto Show documentation
A GWT cryptography library ported from Legion of the Bouncy Castle.
The newest version!
package org.bouncycastle.openpgp.operator.bc;
import java.io.IOException;
import java.io.OutputStream;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.util.encoders.Hex;
/**
* Calculator for the EC based KDF algorithm described in RFC 6637
*/
class RFC6637KDFCalculator
{
// "Anonymous Sender ", which is the octet sequence
private static final byte[] ANONYMOUS_SENDER = Hex.decode("416E6F6E796D6F75732053656E64657220202020");
private final PGPDigestCalculator digCalc;
private final int keyAlgorithm;
public RFC6637KDFCalculator(PGPDigestCalculator digCalc, int keyAlgorithm)
{
this.digCalc = digCalc;
this.keyAlgorithm = keyAlgorithm;
}
public byte[] createKey(ECPoint s, byte[] userKeyingMaterial)
throws PGPException
{
try
{
// RFC 6637 - Section 8
return KDF(digCalc, s, getKeyLen(keyAlgorithm), userKeyingMaterial);
}
catch (IOException e)
{
throw new PGPException("Exception performing KDF: " + e.getMessage(), e);
}
}
// RFC 6637 - Section 7
// Implements KDF( X, oBits, Param );
// Input: point X = (x,y)
// oBits - the desired size of output
// hBits - the size of output of hash function Hash
// Param - octets representing the parameters
// Assumes that oBits <= hBits
// Convert the point X to the octet string, see section 6:
// ZB' = 04 || x || y
// and extract the x portion from ZB'
// ZB = x;
// MB = Hash ( 00 || 00 || 00 || 01 || ZB || Param );
// return oBits leftmost bits of MB.
private static byte[] KDF(PGPDigestCalculator digCalc, ECPoint s, int keyLen, byte[] param)
throws IOException
{
byte[] ZB = s.getXCoord().getEncoded();
OutputStream dOut = digCalc.getOutputStream();
dOut.write(0x00);
dOut.write(0x00);
dOut.write(0x00);
dOut.write(0x01);
dOut.write(ZB);
dOut.write(param);
byte[] digest = digCalc.getDigest();
byte[] key = new byte[keyLen];
System.arraycopy(digest, 0, key, 0, key.length);
return key;
}
private static int getKeyLen(int algID)
throws PGPException
{
switch (algID)
{
case SymmetricKeyAlgorithmTags.AES_128:
return 16;
case SymmetricKeyAlgorithmTags.AES_192:
return 24;
case SymmetricKeyAlgorithmTags.AES_256:
return 32;
default:
throw new PGPException("unknown symmetric algorithm ID: " + algID);
}
}
}