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 com.google.crypto.tink.aead.AeadKeyTemplates; 20 import com.google.crypto.tink.proto.EcPointFormat; 21 import com.google.crypto.tink.proto.EciesAeadDemParams; 22 import com.google.crypto.tink.proto.EciesAeadHkdfKeyFormat; 23 import com.google.crypto.tink.proto.EciesAeadHkdfParams; 24 import com.google.crypto.tink.proto.EciesHkdfKemParams; 25 import com.google.crypto.tink.proto.EllipticCurveType; 26 import com.google.crypto.tink.proto.HashType; 27 import com.google.crypto.tink.proto.KeyTemplate; 28 import com.google.crypto.tink.proto.OutputPrefixType; 29 import com.google.protobuf.ByteString; 30 31 /** 32 * Pre-generated {@link KeyTemplate} for {@link HybridDecrypt} and {@link HybridEncrypt} primitives. 33 * 34 * <p>We recommend to avoid this class in order to keep dependencies small. 35 * 36 * <ul> 37 * <li>Using this class adds a dependency on protobuf. We hope that eventually it is possible to 38 * use Tink without a dependency on protobuf. 39 * <li>Using this class adds a dependency on classes for all involved key types. 40 * </ul> 41 * 42 * These dependencies all come from static class member variables, which are initialized when the 43 * class is loaded. This implies that static analysis and code minimization tools (such as proguard) 44 * cannot remove the usages either. 45 * 46 * <p>Instead, we recommend to use {@code KeysetHandle.generateEntryFromParametersName} or {@code 47 * KeysetHandle.generateEntryFromParameters}. 48 * 49 * <p>One can use these templates to generate new {@link com.google.crypto.tink.proto.Keyset} with 50 * {@link KeysetHandle#generateNew}. To generate a new keyset that contains a single {@link 51 * com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey}, one can do: 52 * 53 * <pre>{@code 54 * HybridConfig.register(); 55 * KeysetHandle handle = KeysetHandle.generateNew( 56 * HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM); 57 * HybridDecrypt decrypter = handle.getPrimitive(RegistryConfiguration.get(), HybridDecrypt.class); 58 * HybridEncrypt encrypter = 59 * handle.getPublicKeysetHandle() 60 * .getPrimitive(RegistryConfiguration.get(), HybridDecrypt.class); 61 * }</pre> 62 * 63 * @since 1.0.0 64 */ 65 public final class HybridKeyTemplates { 66 private static final byte[] EMPTY_SALT = new byte[0]; 67 /** 68 * A {@link KeyTemplate} that generates new instances of {@link 69 * com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey} with the following parameters: 70 * 71 * <ul> 72 * <li>KEM: ECDH over NIST P-256 73 * <li>DEM: AES128-GCM 74 * <li>KDF: HKDF-HMAC-SHA256 with an empty salt 75 * </ul> 76 * 77 * <p>Unlike other key templates that use AES-GCM, the instances of {@link HybridDecrypt} 78 * generated by this key template has no limitation on Android KitKat (API level 19). They might 79 * not work in older versions though. 80 */ 81 public static final KeyTemplate ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM = 82 createEciesAeadHkdfKeyTemplate( 83 EllipticCurveType.NIST_P256, 84 HashType.SHA256, 85 EcPointFormat.UNCOMPRESSED, 86 AeadKeyTemplates.AES128_GCM, 87 OutputPrefixType.TINK, 88 EMPTY_SALT); 89 90 /** 91 * A {@link KeyTemplate} that generates new instances of {@link 92 * com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey} with the following parameters: 93 * 94 * <ul> 95 * <li>KEM: ECDH over NIST P-256 96 * <li>DEM: AES128-GCM 97 * <li>KDF: HKDF-HMAC-SHA256 with an empty salt 98 * <li>EC Point Format: Compressed 99 * <li>OutputPrefixType: RAW 100 * </ul> 101 * 102 * <p>Unlike other key templates that use AES-GCM, the instances of {@link HybridDecrypt} 103 * generated by this key template has no limitation on Android KitKat (API level 19). They might 104 * not work in older versions though. 105 */ 106 public static final KeyTemplate ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM_COMPRESSED_WITHOUT_PREFIX = 107 createEciesAeadHkdfKeyTemplate( 108 EllipticCurveType.NIST_P256, 109 HashType.SHA256, 110 EcPointFormat.COMPRESSED, 111 AeadKeyTemplates.AES128_GCM, 112 OutputPrefixType.RAW, 113 EMPTY_SALT); 114 115 /** 116 * A {@link KeyTemplate} that generates new instances of {@link 117 * com.google.crypto.tink.proto.EciesAeadHkdfPrivateKey} with the following parameters: 118 * 119 * <ul> 120 * <li>KEM: ECDH over NIST P-256 121 * <li>DEM: AES128-CTR-HMAC-SHA256 with the following parameters 122 * <ul> 123 * <li>AES key size: 16 bytes 124 * <li>AES CTR IV size: 16 bytes 125 * <li>HMAC key size: 32 bytes 126 * <li>HMAC tag size: 16 bytes 127 * </ul> 128 * <li>KDF: HKDF-HMAC-SHA256 with an empty salt 129 * </ul> 130 */ 131 public static final KeyTemplate ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256 = 132 createEciesAeadHkdfKeyTemplate( 133 EllipticCurveType.NIST_P256, 134 HashType.SHA256, 135 EcPointFormat.UNCOMPRESSED, 136 AeadKeyTemplates.AES128_CTR_HMAC_SHA256, 137 OutputPrefixType.TINK, 138 EMPTY_SALT); 139 140 /** 141 * @return a {@link KeyTemplate} containing a {@link EciesAeadHkdfKeyFormat}. 142 * @deprecated Use EciesParameters instead. 143 */ 144 @Deprecated createEciesAeadHkdfKeyTemplate( EllipticCurveType curve, HashType hashType, EcPointFormat ecPointFormat, KeyTemplate demKeyTemplate, OutputPrefixType outputPrefixType, byte[] salt)145 public static KeyTemplate createEciesAeadHkdfKeyTemplate( 146 EllipticCurveType curve, 147 HashType hashType, 148 EcPointFormat ecPointFormat, 149 KeyTemplate demKeyTemplate, 150 OutputPrefixType outputPrefixType, 151 byte[] salt) { 152 EciesAeadHkdfKeyFormat format = EciesAeadHkdfKeyFormat.newBuilder() 153 .setParams( 154 createEciesAeadHkdfParams(curve, hashType, ecPointFormat, demKeyTemplate, salt)) 155 .build(); 156 return KeyTemplate.newBuilder() 157 .setTypeUrl(EciesAeadHkdfPrivateKeyManager.getKeyType()) 158 .setOutputPrefixType(outputPrefixType) 159 .setValue(format.toByteString()) 160 .build(); 161 } 162 163 /** 164 * @return a {@link EciesAeadHkdfParams} with the specified parameters. 165 * @deprecated Use EciesParameters instead. 166 */ 167 @Deprecated createEciesAeadHkdfParams( EllipticCurveType curve, HashType hashType, EcPointFormat ecPointFormat, KeyTemplate demKeyTemplate, byte[] salt)168 public static EciesAeadHkdfParams createEciesAeadHkdfParams( 169 EllipticCurveType curve, 170 HashType hashType, 171 EcPointFormat ecPointFormat, 172 KeyTemplate demKeyTemplate, 173 byte[] salt) { 174 EciesHkdfKemParams kemParams = EciesHkdfKemParams.newBuilder() 175 .setCurveType(curve) 176 .setHkdfHashType(hashType) 177 .setHkdfSalt(ByteString.copyFrom(salt)) 178 .build(); 179 EciesAeadDemParams demParams = EciesAeadDemParams.newBuilder() 180 .setAeadDem(demKeyTemplate) 181 .build(); 182 return EciesAeadHkdfParams.newBuilder() 183 .setKemParams(kemParams) 184 .setDemParams(demParams) 185 .setEcPointFormat(ecPointFormat) 186 .build(); 187 } 188 HybridKeyTemplates()189 private HybridKeyTemplates() {} 190 } 191