![JAR search and dependency download from the Maven repository](/logo.png)
org.bouncycastle.crypto.fips.FipsTripleDES Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bc-fips-debug Show documentation
Show all versions of bc-fips-debug Show documentation
The FIPS 140-2 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-2 level 1. This jar contains the debug version JCE provider and low-level API for the BC-FJA version 1.0.2.3, FIPS Certificate #3514. Please note the debug jar is not certified.
package org.bouncycastle.crypto.fips;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.util.logging.Logger;
import org.bouncycastle.crypto.Algorithm;
import org.bouncycastle.crypto.AuthenticationParametersWithIV;
import org.bouncycastle.crypto.CipherOutputStream;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.IllegalKeyException;
import org.bouncycastle.crypto.InvalidWrappingException;
import org.bouncycastle.crypto.OperatorUsingSecureRandom;
import org.bouncycastle.crypto.OutputEncryptor;
import org.bouncycastle.crypto.PlainInputProcessingException;
import org.bouncycastle.crypto.SymmetricKey;
import org.bouncycastle.crypto.SymmetricSecretKey;
import org.bouncycastle.crypto.general.FipsRegister;
import org.bouncycastle.crypto.internal.BufferedBlockCipher;
import org.bouncycastle.crypto.internal.InvalidCipherTextException;
import org.bouncycastle.crypto.internal.KeyGenerationParameters;
import org.bouncycastle.crypto.internal.Mac;
import org.bouncycastle.crypto.internal.MultiBlockCipher;
import org.bouncycastle.crypto.internal.StreamCipher;
import org.bouncycastle.crypto.internal.ValidatedSymmetricKey;
import org.bouncycastle.crypto.internal.Wrapper;
import org.bouncycastle.crypto.internal.io.CipherInputStream;
import org.bouncycastle.crypto.internal.io.CipherOutputStreamImpl;
import org.bouncycastle.crypto.internal.macs.CMac;
import org.bouncycastle.crypto.internal.params.DesEdeParameters;
import org.bouncycastle.crypto.internal.params.KeyParameter;
import org.bouncycastle.crypto.internal.params.KeyParameterImpl;
import org.bouncycastle.crypto.internal.test.BasicKatTest;
import org.bouncycastle.crypto.internal.wrappers.SP80038FWrapEngine;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Properties;
import org.bouncycastle.util.encoders.Hex;
/**
* Source class for approved implementations of AES based algorithms
*/
public final class FipsTripleDES
{
private static final Logger LOG = Logger.getLogger(FipsTripleDES.class.getName());
private FipsTripleDES()
{
}
/**
* Raw TripleDES algorithm, can be used for creating general purpose TripleDES keys.
*/
public static final FipsAlgorithm ALGORITHM = new FipsAlgorithm("TripleDES");
static final FipsEngineProvider ENGINE_PROVIDER;
/**
* TripleDES in electronic code book(ECB) mode.
*/
public static final Parameters ECB = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB));
/**
* TripleDES in electronic code book mode with PKCS#7/PKCS#5 padding.
*/
public static final Parameters ECBwithPKCS7 = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB, Padding.PKCS7));
/**
* TripleDES in electronic code book mode with ISO10126-2 padding.
*/
public static final Parameters ECBwithISO10126_2 = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB, Padding.ISO10126_2));
/**
* TripleDES in electronic code book mode with X9.23 padding.
*/
public static final Parameters ECBwithX923 = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB, Padding.X923));
/**
* TripleDES in electronic code book mode with ISO7816-4 padding.
*/
public static final Parameters ECBwithISO7816_4 = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB, Padding.ISO7816_4));
/**
* TripleDES in electronic code book mode with trailing bit complement(TBC) padding.
*/
public static final Parameters ECBwithTBC = new Parameters(new FipsAlgorithm(ALGORITHM, Mode.ECB, Padding.TBC));
/**
* TripleDES in cipher block chaining(CBC) mode.
*/
public static final ParametersWithIV CBC = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC));
/**
* TripleDES in cipher block chaining mode with PKCS#7/PKCS#5 padding.
*/
public static final ParametersWithIV CBCwithPKCS7 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.PKCS7));
/**
* TripleDES in cipher block chaining mode with ISO10126-2 padding.
*/
public static final ParametersWithIV CBCwithISO10126_2 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.ISO10126_2));
/**
* TripleDES in cipher block chaining mode with X9.23 padding.
*/
public static final ParametersWithIV CBCwithX923 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.X923));
/**
* TripleDES in cipher block chaining mode with ISO7816-4 padding.
*/
public static final ParametersWithIV CBCwithISO7816_4 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.ISO7816_4));
/**
* TripleDES in cipher block chaining mode with trailing bit complement(TBC) padding.
*/
public static final ParametersWithIV CBCwithTBC = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.TBC));
/**
* TripleDES in cipher block chaining mode cipher text stealing type 1.
*/
public static final ParametersWithIV CBCwithCS1 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.CS1));
/**
* TripleDES in cipher block chaining mode cipher text stealing type 2.
*/
public static final ParametersWithIV CBCwithCS2 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.CS2));
/**
* TripleDES in cipher block chaining mode cipher text stealing type 3.
*/
public static final ParametersWithIV CBCwithCS3 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CBC, Padding.CS3));
/**
* TripleDES in cipher feedback(CFB) mode, 8 bit block size.
*/
public static final ParametersWithIV CFB8 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CFB8));
/**
* TripleDES in output feedback(CFB) mode, 64 bit block size.
*/
public static final ParametersWithIV CFB64 = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CFB64));
/**
* TripleDES in output feedback(OFB) mode, 64 bit blocksize.
*/
public static final ParametersWithIV OFB = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.OFB64));
/**
* TripleDES in counter(CTR) mode.
*/
public static final ParametersWithIV CTR = new ParametersWithIV(new FipsAlgorithm(ALGORITHM, Mode.CTR));
/**
* TripleDES as a FIPS SP800-38F/RFC 3394 key wrapper.
*/
public static final WrapParameters TKW = new WrapParameters(new FipsAlgorithm(ALGORITHM, Mode.WRAP));
/**
* TripleDES CMAC.
*/
public static final AuthParameters CMAC = new AuthParameters(new FipsAlgorithm(ALGORITHM, Mode.CMAC));
static
{
EngineProvider provider = new EngineProvider();
// FSM_STATE:5.TDES.0,"TDES ENCRYPT DECRYPT KAT", "The module is performing TDES encrypt and decrypt KAT self-test"
// FSM_TRANS:5.TDES.0.0,"CONDITIONAL TEST","TDES ENCRYPT DECRYPT KAT", "Invoke TDES Encrypt/Decrypt KAT self-test"
provider.createEngine();
// FSM_TRANS:5.TDES.0.1,"TDES ENCRYPT DECRYPT KAT", "CONDITIONAL TEST", "TDES Encrypt/Decrypt KAT self-test successful completion"
// FSM_TRANS:5.TDES.0.2,"TDES ENCRYPT DECRYPT KAT", "SOFT ERROR", "TDES Encrypt/Decrypt KAT self-test failed"
// FSM_STATE:5.TDES.1,"TDES-CMAC GENERATE VERIFY KAT", "The module is performing TDES-CMAC generate and verify KAT self-test"
// FSM_TRANS:5.TDES.1.0, "CONDITIONAL TEST", "TDES-CMAC GENERATE VERIFY KAT", "Invoke TDES CMAC Generate/Verify KAT self-test"
cmacStartUpTest(provider);
// FSM_TRANS:5.TDES.1.1, "TDES-CMAC GENERATE VERIFY KAT", "POWER ON SELF-TEST", "TDES CMAC Generate/Verify KAT self-test successful completion"
// FSM_TRANS:5.TDES.1.2, "TDES-CMAC GENERATE VERIFY KAT", "SOFT ERROR", "TDES CMAC Generate/Verify KAT self-test failed"
ENGINE_PROVIDER = provider;
FipsRegister.registerEngineProvider(ALGORITHM, provider);
}
/**
* General Triple-DES operator parameters.
*/
public static class Parameters
extends FipsParameters
{
Parameters(FipsAlgorithm algorithm)
{
super(algorithm);
}
}
/**
* General Triple-DES operator parameters. with IV
*/
public static final class ParametersWithIV
extends Parameters
implements org.bouncycastle.crypto.ParametersWithIV
{
private final byte[] iv;
ParametersWithIV(FipsAlgorithm algorithm)
{
this(algorithm, null);
}
private ParametersWithIV(FipsAlgorithm algorithm, byte[] iv)
{
super(algorithm);
((Mode)algorithm.basicVariation()).checkIv(iv, 8);
this.iv = iv;
}
public ParametersWithIV withIV(byte[] iv)
{
return new ParametersWithIV(this.getAlgorithm(), Arrays.clone(iv));
}
public ParametersWithIV withIV(SecureRandom random)
{
return new ParametersWithIV(this.getAlgorithm(), ((Mode)this.getAlgorithm().basicVariation()).createDefaultIvIfNecessary(8, random));
}
public byte[] getIV()
{
return Arrays.clone(iv);
}
}
/**
* Parameters for Triple-DES AEAD and MAC modes..
*/
public static final class AuthParameters
extends FipsParameters
implements AuthenticationParametersWithIV
{
private final byte[] iv;
private final int macLenInBits;
/**
* Base constructor - the algorithm. In this case the tag length defaults to the 128 bits.
*
* @param algorithm algorithm mode.
*/
AuthParameters(FipsAlgorithm algorithm)
{
this(algorithm, null, Utils.getDefaultMacSize(algorithm, 64)); // tag full blocksize or half
}
/**
* Base Constructor that takes an iv (nonce) and a tag length.
*
* @param algorithm algorithm mode.
* @param iv iv, or nonce, to be used with this algorithm.
* @param macLenInBits length of the checksum tag in bits.
*/
private AuthParameters(FipsAlgorithm algorithm, byte[] iv, int macLenInBits)
{
super(algorithm);
this.iv = iv;
this.macLenInBits = macLenInBits;
}
public int getMACSizeInBits()
{
return macLenInBits;
}
public byte[] getIV()
{
return Arrays.clone(iv);
}
public AuthParameters withIV(byte[] iv)
{
return new AuthParameters(this.getAlgorithm(), Arrays.clone(iv), this.macLenInBits);
}
public AuthParameters withIV(SecureRandom random)
{
return new AuthParameters(this.getAlgorithm(), this.getAlgorithm().createDefaultIvIfNecessary(8, random), this.macLenInBits);
}
/**
* @param random source of randomness for iv (nonce)
* @param ivLen length of the iv (nonce) in bytes to use with the algorithm.
*/
public AuthParameters withIV(SecureRandom random, int ivLen)
{
return new AuthParameters(this.getAlgorithm(), this.getAlgorithm().createIvIfNecessary(ivLen, random), this.macLenInBits);
}
public AuthParameters withMACSize(int macSizeInBits)
{
return new AuthParameters(this.getAlgorithm(), org.bouncycastle.util.Arrays.clone(iv), macSizeInBits);
}
}
/**
* Parameters for Triple-DES key wrap operators.
*/
public static final class WrapParameters
extends FipsParameters
{
private final boolean useInverse;
WrapParameters(FipsAlgorithm algorithm)
{
this(algorithm, false);
}
private WrapParameters(FipsAlgorithm algorithm, boolean useInverse)
{
super(algorithm);
this.useInverse = useInverse;
}
public boolean isUsingInverseFunction()
{
return useInverse;
}
public WrapParameters withUsingInverseFunction(boolean useInverse)
{
return new WrapParameters(getAlgorithm(), useInverse);
}
}
/**
* Triple-DES key generator.
*/
public static final class KeyGenerator
extends FipsSymmetricKeyGenerator
{
private final FipsAlgorithm algorithm;
private final int keySizeInBits;
private final SecureRandom random;
/**
* Constructor to generate a general purpose Triple-DES key.
*
* @param keySizeInBits size of the key in bits.
* @param random secure random to use in key construction.
*/
public KeyGenerator(int keySizeInBits, SecureRandom random)
{
this(ALGORITHM, keySizeInBits, random);
}
/**
* Constructor to generate a specific purpose Triple-DES key for an algorithm in a particular parameter set.
*
* @param parameterSet FIPS algorithm key is for,
* @param keySizeInBits size of the key in bits.
* @param random secure random to use in key construction.
*/
public KeyGenerator(FipsParameters parameterSet, int keySizeInBits, SecureRandom random)
{
this(parameterSet.getAlgorithm(), keySizeInBits, random);
}
private KeyGenerator(FipsAlgorithm algorithm, int keySizeInBits, SecureRandom random)
{
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
Utils.validateKeyGenRandom(random, 112, algorithm);
if (keySizeInBits != 168 && keySizeInBits != 192)
{
throw new IllegalArgumentException("Attempt to create key with unapproved key size [" + keySizeInBits + "]: " + algorithm.getName());
}
}
else
{
if (keySizeInBits != 112 && keySizeInBits != 168 && keySizeInBits != 128 && keySizeInBits != 192)
{
throw new IllegalArgumentException("Attempt to create key with invalid key size [" + keySizeInBits + "]: " + algorithm.getName());
}
}
this.algorithm = algorithm;
this.keySizeInBits = keySizeInBits;
this.random = random;
}
public SymmetricKey generateKey()
{
CipherKeyGenerator cipherKeyGenerator = new DesEdeKeyGenerator(algorithm);
cipherKeyGenerator.init(new KeyGenerationParameters(random, keySizeInBits));
return new SymmetricSecretKey(algorithm, cipherKeyGenerator.generateKey());
}
}
/**
* Factory for basic Triple-DES encryption/decryption operators.
*/
public static final class OperatorFactory
extends FipsSymmetricOperatorFactory
{
@Override
public FipsOutputEncryptor createOutputEncryptor(final SymmetricKey key, final Parameters parameters)
{
final ValidatedSymmetricKey sKey = validateKey(key, parameters, false);
return new OutEncryptor(sKey, parameters, null);
}
@Override
public FipsOutputDecryptor createOutputDecryptor(final SymmetricKey key, final Parameters parameters)
{
ValidatedSymmetricKey sKey = validateKey(key, parameters, true);
final BufferedBlockCipher cipher = BlockCipherUtils.createStandardCipher(false, sKey, ENGINE_PROVIDER, parameters, null);
return new FipsOutputDecryptor()
{
@Override
public Parameters getParameters()
{
return parameters;
}
public int getMaxOutputSize(int inputLen)
{
return cipher.getOutputSize(inputLen);
}
public int getUpdateOutputSize(int inputLen)
{
return cipher.getUpdateOutputSize(inputLen);
}
@Override
public CipherOutputStream getDecryptingStream(OutputStream out)
{
if (cipher.getUnderlyingCipher() instanceof StreamCipher)
{
return CipherOutputStreamImpl.getInstance(out, (StreamCipher)cipher.getUnderlyingCipher());
}
return CipherOutputStreamImpl.getInstance(out, cipher);
}
};
}
@Override
public FipsInputDecryptor createInputDecryptor(final SymmetricKey key, final Parameters parameters)
{
final ValidatedSymmetricKey sKey = validateKey(key, parameters, true);
final BufferedBlockCipher cipher = BlockCipherUtils.createStandardCipher(false, sKey, ENGINE_PROVIDER, parameters, null);
return new FipsInputDecryptor()
{
@Override
public Parameters getParameters()
{
return parameters;
}
@Override
public InputStream getDecryptingStream(InputStream in)
{
if (cipher.getUnderlyingCipher() instanceof StreamCipher)
{
return new CipherInputStream(in, (StreamCipher)cipher.getUnderlyingCipher());
}
return new CipherInputStream(in, cipher);
}
};
}
private class OutEncryptor
extends FipsOutputEncryptor
implements OperatorUsingSecureRandom>
{
private final Parameters parameters;
private final ValidatedSymmetricKey key;
private final BufferedBlockCipher cipher;
public OutEncryptor(ValidatedSymmetricKey key, Parameters parameters, SecureRandom random)
{
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
if (!Properties.isOverrideSet("org.bouncycastle.tripledes.allow_enc"))
{
throw new FipsUnapprovedOperationError("Triple-DES encryption disallowed");
}
LOG.warning("Triple-DES encryption detected: no longer an approved operation but override set");
}
this.key = key;
this.parameters = parameters;
cipher = BlockCipherUtils.createStandardCipher(true, key, ENGINE_PROVIDER, parameters, random);
}
public CipherOutputStream getEncryptingStream(OutputStream out)
{
if (cipher.getUnderlyingCipher() instanceof StreamCipher)
{
return CipherOutputStreamImpl.getInstance(out, (StreamCipher)cipher.getUnderlyingCipher());
}
return CipherOutputStreamImpl.getInstance(out, cipher);
}
public OutputEncryptor withSecureRandom(SecureRandom random)
{
return new OutEncryptor(key, parameters, random);
}
public Parameters getParameters()
{
return parameters;
}
public int getMaxOutputSize(int inputLen)
{
return cipher.getOutputSize(inputLen);
}
public int getUpdateOutputSize(int inputLen)
{
return cipher.getUpdateOutputSize(inputLen);
}
}
}
/**
* Factory for producing FIPS Triple-DES MAC calculators.
*/
public static final class MACOperatorFactory
extends FipsMACOperatorFactory
{
@Override
protected int calculateMACSize(AuthParameters parameters)
{
return makeMAC(parameters).getMacSize();
}
@Override
protected Mac createMAC(SymmetricKey key, final AuthParameters parameters)
{
final Mac mac = makeMAC(parameters);
ValidatedSymmetricKey sKey = validateKey(key, parameters, false);
if (parameters.getIV() != null)
{
mac.init(Utils.getParametersWithIV(sKey, parameters.getIV()));
}
else
{
mac.init(Utils.getKeyParameter(sKey));
}
return mac;
}
}
static FipsEngineProvider getMacProvider(final FipsAlgorithm algorithm)
{
final FipsEngineProvider macProvider;
switch (((Mode)algorithm.basicVariation()))
{
case CMAC:
macProvider = new FipsEngineProvider()
{
public Mac createEngine()
{
return new CMac(ENGINE_PROVIDER.createEngine());
}
};
break;
default:
throw new IllegalArgumentException("Unknown algorithm passed to FipsTripleDES MAC Provider: " + algorithm);
}
return macProvider;
}
static Mac makeMAC(final AuthParameters authParameters)
{
final Mac mac;
switch (((Mode)authParameters.getAlgorithm().basicVariation()))
{
case CMAC:
mac = new CMac(ENGINE_PROVIDER.createEngine(), authParameters.macLenInBits);
break;
default:
throw new IllegalArgumentException("Unknown algorithm passed to FipsTripleDES.OperatorFactory.createMACCalculator: " + authParameters.getAlgorithm());
}
return mac;
}
/**
* Factory for producing FIPS Triple-DES key wrap/unwrap operators.
*/
public static final class KeyWrapOperatorFactory
extends FipsKeyWrapOperatorFactory
{
private Wrapper createWrapper(FipsAlgorithm algorithm, boolean useInverse)
{
Wrapper cipher;
switch (((Mode)algorithm.basicVariation()))
{
case WRAP:
cipher = new SP80038FWrapEngine(ENGINE_PROVIDER.createEngine(), useInverse);
break;
default:
throw new IllegalArgumentException("Unknown algorithm passed to FipsDESEDE.KeyWrapOperatorFactory: " + algorithm.getName());
}
return cipher;
}
@Override
public FipsKeyWrapper createKeyWrapper(SymmetricKey key, final WrapParameters parameters)
{
ValidatedSymmetricKey sKey = validateKey(key, parameters, false);
final Wrapper wrapper = createWrapper(parameters.getAlgorithm(), parameters.useInverse);
wrapper.init(true, new KeyParameterImpl(sKey.getKeyBytes()));
return new FipsKeyWrapper()
{
public WrapParameters getParameters()
{
return parameters;
}
public byte[] wrap(byte[] in, int inOff, int inLen)
throws PlainInputProcessingException
{
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
if (!Properties.isOverrideSet("org.bouncycastle.tripledes.allow_wrap"))
{
throw new FipsUnapprovedOperationError("Triple-DES encryption key-wrapping disallowed");
}
LOG.warning("Triple-DES encryption key-wrapping detected: no longer an approved operation but override set");
}
try
{
return wrapper.wrap(in, inOff, inLen);
}
catch (Exception e)
{
throw new PlainInputProcessingException("Unable to wrap key: " + e.getMessage(), e);
}
}
};
}
@Override
public FipsKeyUnwrapper createKeyUnwrapper(SymmetricKey key, final WrapParameters parameters)
{
ValidatedSymmetricKey sKey = validateKey(key, parameters, true);
final Wrapper wrapper = createWrapper(parameters.getAlgorithm(), parameters.useInverse);
wrapper.init(false, new KeyParameterImpl(sKey.getKeyBytes()));
return new FipsKeyUnwrapper()
{
public WrapParameters getParameters()
{
return parameters;
}
@Override
public byte[] unwrap(byte[] in, int inOff, int inLen)
throws InvalidWrappingException
{
try
{
return wrapper.unwrap(in, inOff, inLen);
}
catch (InvalidCipherTextException e)
{
throw new InvalidWrappingException("Unable to unwrap key: " + e.getMessage(), e);
}
}
};
}
}
private static void validateKeySize(Algorithm algorithm, int keySize)
{
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
if (keySize != 168 && keySize != 192)
{
// FSM_TRANS:5.TDES.2.2,"TDES KEY VALIDITY TEST", "USER COMMAND REJECTED", "Validity test on TDES key failed"
throw new IllegalKeyException("Key must be of length 192 bits: " + algorithm.getName());
}
}
else
{
if (keySize != 112 && keySize != 168 && keySize != 128 && keySize != 192)
{
throw new IllegalKeyException("Key must be of length 128 or 192 bits: " + algorithm.getName());
}
}
}
private static ValidatedSymmetricKey validateKey(SymmetricKey key, org.bouncycastle.crypto.Parameters parameters, boolean forReading)
{
// FSM_STATE:5.TDES.2,"TDES KEY VALIDITY TEST", "The module is validating the size and purpose of an TDES key"
// FSM_TRANS:5.TDES.2.0,"CONDITIONAL TEST", "TDES KEY VALIDITY TEST", "Invoke Validity test on TDES key"
ValidatedSymmetricKey vKey = PrivilegedUtils.getValidatedKey(key);
int keyLength = vKey.getKeySizeInBits();
if (!(forReading && keyLength == 128)) // decryption using 2 key TDES okay,
{
validateKeySize(key.getAlgorithm(), keyLength);
if (CryptoServicesRegistrar.isInApprovedOnlyMode())
{
if (!forReading && !DesEdeParameters.isReal3Key(vKey.getKeyBytes()))
{
// FSM_TRANS:5.TDES.2.2,"TDES KEY VALIDITY TEST", "USER COMMAND REJECTED", "Validity test on TDES key failed"
throw new IllegalKeyException("Key not real 3-Key DESEDE key");
}
}
}
if (!Properties.isOverrideSet("org.bouncycastle.tripledes.allow_weak"))
{
if (!forReading)
{
if (DesEdeParameters.isActuallyDesKey(vKey.getKeyBytes()))
{
// FSM_TRANS:5.TDES.2.2,"TDES KEY VALIDITY TEST", "USER COMMAND REJECTED", "Validity test on TDES key failed"
throw new IllegalKeyException("Attempt to use repeated DES key: " + key.getAlgorithm().getName());
}
if (DesEdeParameters.isWeakKey(vKey.getKeyBytes(), 0, vKey.getKeyBytes().length))
{
// FSM_TRANS:5.TDES.2.2,"TDES KEY VALIDITY TEST", "USER COMMAND REJECTED", "Validity test on TDES key failed"
throw new IllegalKeyException("Attempt to use weak key: " + key.getAlgorithm().getName());
}
}
}
Algorithm algorithm = key.getAlgorithm();
if (!algorithm.equals(ALGORITHM))
{
if (!algorithm.equals(parameters.getAlgorithm()))
{
// FSM_TRANS:5.TDES.2.2,"TDES KEY VALIDITY TEST", "USER COMMAND REJECTED", "Validity test on TDES key failed"
throw new IllegalKeyException("FIPS Key not for specified algorithm");
}
}
// FSM_TRANS:5.TDES.2.1,"TDES KEY VALIDITY TEST", "CONDITIONAL TEST", "Validity test on TDES key successful"
return vKey;
}
private static final class EngineProvider
extends FipsEngineProvider
{
private static byte[] input = Hex.decode("4e6f772069732074");
private static byte[] output = Hex.decode("f7cfbe5e6c38b35a");
private static final byte[] keyBytes = Hex.decode("0102020404070708080b0b0d0d0e0e101013131515161619");
public MultiBlockCipher createEngine()
{
return SelfTestExecutor.validate(ALGORITHM, new DesEdeEngine(), new VariantKatTest()
{
public void evaluate(DesEdeEngine tripleDesEngine)
{
byte[] tmp = new byte[input.length];
KeyParameter key = new KeyParameterImpl(keyBytes);
tripleDesEngine.init(true, key);
tripleDesEngine.processBlock(input, 0, tmp, 0);
if (!Arrays.areEqual(output, tmp))
{
fail("Failed self test on encryption");
}
tripleDesEngine.init(false, key);
tripleDesEngine.processBlock(tmp, 0, tmp, 0);
if (!Arrays.areEqual(input, tmp))
{
fail("Failed self test on decryption");
}
}
});
}
}
private static void cmacStartUpTest(EngineProvider provider)
{
SelfTestExecutor.validate(ALGORITHM, provider, new BasicKatTest()
{
public boolean hasTestPassed(EngineProvider provider)
throws Exception
{
byte[] input16 = Hex.decode("6bc1bee22e409f96e93d7e117393172a");
byte[] output_k128_m16 = Hex.decode("c0b9bbee139722ab");
Mac mac = new CMac(provider.createEngine(), 64);
//128 bytes key
KeyParameter key = new KeyParameterImpl(Hex.decode("0102020404070708080b0b0d0d0e0e101013131515161619"));
// 0 bytes message - 128 bytes key
mac.init(key);
mac.update(input16, 0, input16.length);
byte[] out = new byte[8];
mac.doFinal(out, 0);
return Arrays.areEqual(out, output_k128_m16);
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy