1 // Copyright 2017 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 package com.google.crypto.tink.hybrid; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertTrue; 22 23 import com.google.crypto.tink.TinkProtoParametersFormat; 24 import com.google.crypto.tink.aead.AeadKeyTemplates; 25 import com.google.crypto.tink.proto.EcPointFormat; 26 import com.google.crypto.tink.proto.EciesAeadHkdfKeyFormat; 27 import com.google.crypto.tink.proto.EciesHkdfKemParams; 28 import com.google.crypto.tink.proto.EllipticCurveType; 29 import com.google.crypto.tink.proto.HashType; 30 import com.google.crypto.tink.proto.KeyTemplate; 31 import com.google.crypto.tink.proto.OutputPrefixType; 32 import com.google.protobuf.ExtensionRegistryLite; 33 import java.nio.charset.Charset; 34 import org.junit.BeforeClass; 35 import org.junit.Test; 36 import org.junit.experimental.theories.DataPoints; 37 import org.junit.experimental.theories.FromDataPoints; 38 import org.junit.experimental.theories.Theories; 39 import org.junit.experimental.theories.Theory; 40 import org.junit.runner.RunWith; 41 42 /** Tests for HybridKeyTemplates. */ 43 @RunWith(Theories.class) 44 public class HybridKeyTemplatesTest { 45 @BeforeClass setUp()46 public static void setUp() throws Exception { 47 HybridConfig.register(); 48 } 49 50 private static final Charset UTF_8 = Charset.forName("UTF-8"); 51 52 @Test eciesP256HkdfHmaSha256Aes128Gcm()53 public void eciesP256HkdfHmaSha256Aes128Gcm() throws Exception { 54 KeyTemplate template = HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM; 55 assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); 56 assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); 57 EciesAeadHkdfKeyFormat format = 58 EciesAeadHkdfKeyFormat.parseFrom( 59 template.getValue(), ExtensionRegistryLite.getEmptyRegistry()); 60 61 assertTrue(format.hasParams()); 62 assertTrue(format.getParams().hasKemParams()); 63 assertTrue(format.getParams().hasDemParams()); 64 assertTrue(format.getParams().getDemParams().hasAeadDem()); 65 assertEquals(EcPointFormat.UNCOMPRESSED, format.getParams().getEcPointFormat()); 66 EciesHkdfKemParams kemParams = format.getParams().getKemParams(); 67 assertEquals(EllipticCurveType.NIST_P256, kemParams.getCurveType()); 68 assertEquals(HashType.SHA256, kemParams.getHkdfHashType()); 69 assertTrue(kemParams.getHkdfSalt().isEmpty()); 70 assertEquals(AeadKeyTemplates.AES128_GCM.toString(), 71 format.getParams().getDemParams().getAeadDem().toString()); 72 } 73 74 @Test eciesP256HkdfHmacSha256Aes128GcmCompressedWithoutPrefix()75 public void eciesP256HkdfHmacSha256Aes128GcmCompressedWithoutPrefix() throws Exception { 76 KeyTemplate template = 77 HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM_COMPRESSED_WITHOUT_PREFIX; 78 assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); 79 assertEquals(OutputPrefixType.RAW, template.getOutputPrefixType()); 80 EciesAeadHkdfKeyFormat format = 81 EciesAeadHkdfKeyFormat.parseFrom( 82 template.getValue(), ExtensionRegistryLite.getEmptyRegistry()); 83 84 assertTrue(format.hasParams()); 85 assertTrue(format.getParams().hasKemParams()); 86 assertTrue(format.getParams().hasDemParams()); 87 assertTrue(format.getParams().getDemParams().hasAeadDem()); 88 assertEquals(EcPointFormat.COMPRESSED, format.getParams().getEcPointFormat()); 89 EciesHkdfKemParams kemParams = format.getParams().getKemParams(); 90 assertEquals(EllipticCurveType.NIST_P256, kemParams.getCurveType()); 91 assertEquals(HashType.SHA256, kemParams.getHkdfHashType()); 92 assertTrue(kemParams.getHkdfSalt().isEmpty()); 93 assertEquals(AeadKeyTemplates.AES128_GCM.toString(), 94 format.getParams().getDemParams().getAeadDem().toString()); 95 } 96 97 @Test eciesP256HkdfHmacSha256Aes128CtrHmacSha256()98 public void eciesP256HkdfHmacSha256Aes128CtrHmacSha256() throws Exception { 99 KeyTemplate template = HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256; 100 assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); 101 assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); 102 EciesAeadHkdfKeyFormat format = 103 EciesAeadHkdfKeyFormat.parseFrom( 104 template.getValue(), ExtensionRegistryLite.getEmptyRegistry()); 105 106 assertTrue(format.hasParams()); 107 assertTrue(format.getParams().hasKemParams()); 108 assertTrue(format.getParams().hasDemParams()); 109 assertTrue(format.getParams().getDemParams().hasAeadDem()); 110 assertEquals(EcPointFormat.UNCOMPRESSED, format.getParams().getEcPointFormat()); 111 EciesHkdfKemParams kemParams = format.getParams().getKemParams(); 112 assertEquals(EllipticCurveType.NIST_P256, kemParams.getCurveType()); 113 assertEquals(HashType.SHA256, kemParams.getHkdfHashType()); 114 assertTrue(kemParams.getHkdfSalt().isEmpty()); 115 assertEquals(AeadKeyTemplates.AES128_CTR_HMAC_SHA256.toString(), 116 format.getParams().getDemParams().getAeadDem().toString()); 117 } 118 119 @Test testCreateEciesAeadHkdfKeyTemplate()120 public void testCreateEciesAeadHkdfKeyTemplate() throws Exception { 121 // Intentionally using "weird" or invalid values for parameters, 122 // to test that the function correctly puts them in the resulting template. 123 EllipticCurveType curveType = EllipticCurveType.NIST_P384; 124 HashType hashType = HashType.SHA512; 125 EcPointFormat ecPointFormat = EcPointFormat.COMPRESSED; 126 KeyTemplate demKeyTemplate = AeadKeyTemplates.AES256_EAX; 127 String salt = "some salt"; 128 KeyTemplate template = HybridKeyTemplates.createEciesAeadHkdfKeyTemplate( 129 curveType, hashType, ecPointFormat, demKeyTemplate, 130 OutputPrefixType.TINK, salt.getBytes(UTF_8)); 131 assertEquals(EciesAeadHkdfPrivateKeyManager.getKeyType(), template.getTypeUrl()); 132 assertEquals(OutputPrefixType.TINK, template.getOutputPrefixType()); 133 EciesAeadHkdfKeyFormat format = 134 EciesAeadHkdfKeyFormat.parseFrom( 135 template.getValue(), ExtensionRegistryLite.getEmptyRegistry()); 136 137 assertTrue(format.hasParams()); 138 assertTrue(format.getParams().hasKemParams()); 139 assertTrue(format.getParams().hasDemParams()); 140 assertTrue(format.getParams().getDemParams().hasAeadDem()); 141 assertEquals(ecPointFormat, format.getParams().getEcPointFormat()); 142 EciesHkdfKemParams kemParams = format.getParams().getKemParams(); 143 assertEquals(curveType, kemParams.getCurveType()); 144 assertEquals(hashType, kemParams.getHkdfHashType()); 145 assertEquals(salt, kemParams.getHkdfSalt().toStringUtf8()); 146 assertEquals(AeadKeyTemplates.AES256_EAX.toString(), 147 format.getParams().getDemParams().getAeadDem().toString()); 148 } 149 150 public static class Pair { Pair(KeyTemplate template, HybridParameters parameters)151 public Pair(KeyTemplate template, HybridParameters parameters) { 152 this.template = template; 153 this.parameters = parameters; 154 } 155 156 KeyTemplate template; 157 HybridParameters parameters; 158 } 159 160 @DataPoints("EquivalentPairs") 161 public static final Pair[] TEMPLATES = 162 new Pair[] { 163 new Pair( 164 HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM, 165 PredefinedHybridParameters.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM), 166 new Pair( 167 HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM_COMPRESSED_WITHOUT_PREFIX, 168 PredefinedHybridParameters 169 .ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM_COMPRESSED_WITHOUT_PREFIX), 170 new Pair( 171 HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256, 172 PredefinedHybridParameters.ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256), 173 }; 174 175 @Theory testParametersEqualsKeyTemplate(@romDataPoints"EquivalentPairs") Pair p)176 public void testParametersEqualsKeyTemplate(@FromDataPoints("EquivalentPairs") Pair p) 177 throws Exception { 178 assertThat(TinkProtoParametersFormat.parse(p.template.toByteArray())).isEqualTo(p.parameters); 179 } 180 } 181