|
| 1 | +package org.bouncycastle.crypto.test; |
| 2 | + |
| 3 | +import org.bouncycastle.crypto.CipherParameters; |
| 4 | +import org.bouncycastle.crypto.engines.CryptoProWrapEngine; |
| 5 | +import org.bouncycastle.crypto.engines.GOST28147Engine; |
| 6 | +import org.bouncycastle.crypto.params.KeyParameter; |
| 7 | +import org.bouncycastle.crypto.params.ParametersWithSBox; |
| 8 | +import org.bouncycastle.crypto.params.ParametersWithUKM; |
| 9 | +import org.bouncycastle.util.encoders.Hex; |
| 10 | +import org.bouncycastle.util.test.SimpleTest; |
| 11 | + |
| 12 | +/** |
| 13 | + * {@link CryptoProWrapEngine} (RFC 4357 sec. 6.3, with the sec. 6.5 KEK diversification) given no |
| 14 | + * S-box uses the GOST 28147 engine's default one throughout, and never modifies the caller's key. |
| 15 | + */ |
| 16 | +public class CryptoProWrapEngineTest |
| 17 | + extends SimpleTest |
| 18 | +{ |
| 19 | + private static final byte[] KEK = Hex.decode("8b2f3a41c6d5e7091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f7081"); |
| 20 | + private static final byte[] CEK = Hex.decode("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20"); |
| 21 | + private static final byte[] UKM = Hex.decode("1d80603c8544c727"); |
| 22 | + |
| 23 | + public String getName() |
| 24 | + { |
| 25 | + return "CryptoProWrapEngine"; |
| 26 | + } |
| 27 | + |
| 28 | + public void performTest() |
| 29 | + throws Exception |
| 30 | + { |
| 31 | + defaultSBoxTest(); |
| 32 | + |
| 33 | + keyUnmodifiedTest(null); |
| 34 | + keyUnmodifiedTest(GOST28147Engine.getSBox("E-A")); |
| 35 | + } |
| 36 | + |
| 37 | + private void defaultSBoxTest() |
| 38 | + throws Exception |
| 39 | + { |
| 40 | + CryptoProWrapEngine engine = new CryptoProWrapEngine(); |
| 41 | + |
| 42 | + engine.init(true, new ParametersWithUKM( |
| 43 | + new ParametersWithSBox(new KeyParameter(KEK), GOST28147Engine.getSBox("Default")), UKM)); |
| 44 | + byte[] expected = engine.wrap(CEK, 0, CEK.length); |
| 45 | + |
| 46 | + engine.init(true, new ParametersWithUKM(new KeyParameter(KEK), UKM)); |
| 47 | + isTrue("no S-box wrap differs from the default S-box", areEqual(expected, engine.wrap(CEK, 0, CEK.length))); |
| 48 | + |
| 49 | + engine.init(false, new ParametersWithUKM(new KeyParameter(KEK), UKM)); |
| 50 | + isTrue("no S-box unwrap failed", areEqual(CEK, engine.unwrap(expected, 0, expected.length))); |
| 51 | + } |
| 52 | + |
| 53 | + private void keyUnmodifiedTest(byte[] sBox) |
| 54 | + throws Exception |
| 55 | + { |
| 56 | + String label = sBox == null ? "no S-box" : "S-box"; |
| 57 | + |
| 58 | + KeyParameter key = new KeyParameter(KEK); |
| 59 | + CipherParameters kParam = key; |
| 60 | + if (sBox != null) |
| 61 | + { |
| 62 | + kParam = new ParametersWithSBox(kParam, sBox); |
| 63 | + } |
| 64 | + ParametersWithUKM params = new ParametersWithUKM(kParam, UKM); |
| 65 | + |
| 66 | + CryptoProWrapEngine engine = new CryptoProWrapEngine(); |
| 67 | + |
| 68 | + engine.init(true, params); |
| 69 | + byte[] wrapped = engine.wrap(CEK, 0, CEK.length); |
| 70 | + isTrue(label + ": caller's key modified by init", areEqual(KEK, key.getKey())); |
| 71 | + |
| 72 | + engine.init(true, params); |
| 73 | + isTrue(label + ": wrap differs on re-init with the same parameters", |
| 74 | + areEqual(wrapped, engine.wrap(CEK, 0, CEK.length))); |
| 75 | + |
| 76 | + engine.init(false, params); |
| 77 | + isTrue(label + ": unwrap with the same parameters failed", areEqual(CEK, engine.unwrap(wrapped, 0, wrapped.length))); |
| 78 | + isTrue(label + ": caller's key modified by re-init", areEqual(KEK, key.getKey())); |
| 79 | + } |
| 80 | + |
| 81 | + public static void main(String[] args) |
| 82 | + { |
| 83 | + runTest(new CryptoProWrapEngineTest()); |
| 84 | + } |
| 85 | +} |
0 commit comments