org.bouncycastle.bcpg.S2K Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpg-fips Show documentation
Show all versions of bcpg-fips Show documentation
The Bouncy Castle Java APIs for the OpenPGP Protocol. The APIs are designed primarily to be used in conjunction with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.
package org.bouncycastle.bcpg;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Parameter specifier for the PGP string-to-key password based key derivation function.
*
* In iterated mode, S2K takes a single byte iteration count specifier, which is converted to an
* actual iteration count using a formula that grows the iteration count exponentially as the byte
* value increases.
*
* e.g. 0x01
== 1088 iterations, and 0xFF
== 65,011,712 iterations.
*
*/
public class S2K
extends BCPGObject
{
private static final int EXPBIAS = 6;
/** Simple key generation. A single non-salted iteration of a hash function */
public static final int SIMPLE = 0;
/** Salted key generation. A single iteration of a hash function with a (unique) salt */
public static final int SALTED = 1;
/** Salted and iterated key generation. Multiple iterations of a hash function, with a salt */
public static final int SALTED_AND_ITERATED = 3;
public static final int GNU_DUMMY_S2K = 101;
public static final int GNU_PROTECTION_MODE_NO_PRIVATE_KEY = 1;
public static final int GNU_PROTECTION_MODE_DIVERT_TO_CARD = 2;
int type;
int algorithm;
byte[] iv;
int itCount = -1;
int protectionMode = -1;
S2K(
InputStream in)
throws IOException
{
DataInputStream dIn = new DataInputStream(in);
type = dIn.read();
algorithm = dIn.read();
//
// if this happens we have a dummy-S2K packet.
//
if (type != GNU_DUMMY_S2K)
{
if (type != 0)
{
iv = new byte[8];
dIn.readFully(iv, 0, iv.length);
if (type == 3)
{
itCount = dIn.read();
}
}
}
else
{
dIn.read(); // G
dIn.read(); // N
dIn.read(); // U
protectionMode = dIn.read(); // protection mode
}
}
/**
* Constructs a specifier for a {@link #SIMPLE simple} S2K generation.
*
* @param algorithm the {@link HashAlgorithmTags digest algorithm} to use.
*/
public S2K(
int algorithm)
{
this.type = 0;
this.algorithm = algorithm;
}
/**
* Constructs a specifier for a {@link #SALTED salted} S2K generation.
*
* @param algorithm the {@link HashAlgorithmTags digest algorithm} to use.
* @param iv the salt to apply to input to the key generation.
*/
public S2K(
int algorithm,
byte[] iv)
{
this.type = 1;
this.algorithm = algorithm;
this.iv = iv;
}
/**
* Constructs a specifier for a {@link #SALTED_AND_ITERATED salted and iterated} S2K generation.
*
* @param algorithm the {@link HashAlgorithmTags digest algorithm} to iterate.
* @param iv the salt to apply to input to the key generation.
* @param itCount the single byte iteration count specifier.
*/
public S2K(
int algorithm,
byte[] iv,
int itCount)
{
this.type = 3;
this.algorithm = algorithm;
this.iv = iv;
this.itCount = itCount;
}
/**
* Gets the {@link HashAlgorithmTags digest algorithm} specified.
*/
public int getType()
{
return type;
}
/**
* Gets the {@link HashAlgorithmTags hash algorithm} for this S2K.
*/
public int getHashAlgorithm()
{
return algorithm;
}
/**
* Gets the iv/salt to use for the key generation.
*/
public byte[] getIV()
{
return iv;
}
/**
* Gets the actual (expanded) iteration count.
*/
public long getIterationCount()
{
return (16 + (itCount & 15)) << ((itCount >> 4) + EXPBIAS);
}
/**
* Gets the protection mode - only if GNU_DUMMY_S2K
*/
public int getProtectionMode()
{
return protectionMode;
}
public void encode(
BCPGOutputStream out)
throws IOException
{
out.write(type);
out.write(algorithm);
if (type != GNU_DUMMY_S2K)
{
if (type != 0)
{
out.write(iv);
}
if (type == 3)
{
out.write(itCount);
}
}
else
{
out.write('G');
out.write('N');
out.write('U');
out.write(protectionMode);
}
}
}