• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.aead;
18 
19 import static com.google.crypto.tink.internal.TinkBugException.exceptionIsBug;
20 
21 import com.google.crypto.tink.AccessesPartialKey;
22 import com.google.crypto.tink.Aead;
23 import com.google.crypto.tink.KeyManager;
24 import com.google.crypto.tink.KeyTemplate;
25 import com.google.crypto.tink.Parameters;
26 import com.google.crypto.tink.aead.internal.AesEaxProtoSerialization;
27 import com.google.crypto.tink.config.internal.TinkFipsUtil;
28 import com.google.crypto.tink.internal.KeyManagerRegistry;
29 import com.google.crypto.tink.internal.LegacyKeyManagerImpl;
30 import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
31 import com.google.crypto.tink.internal.MutableParametersRegistry;
32 import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
33 import com.google.crypto.tink.internal.PrimitiveConstructor;
34 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
35 import com.google.crypto.tink.subtle.AesEaxJce;
36 import com.google.crypto.tink.util.SecretBytes;
37 import java.security.GeneralSecurityException;
38 import java.util.Collections;
39 import java.util.HashMap;
40 import java.util.Map;
41 import javax.annotation.Nullable;
42 
43 /**
44  * This key manager generates new {@code AesEaxKey} keys and produces new instances of {@code
45  * AesEaxJce}.
46  */
47 public final class AesEaxKeyManager {
validate(AesEaxParameters parameters)48   private static final void validate(AesEaxParameters parameters) throws GeneralSecurityException {
49     if (parameters.getKeySizeBytes() == 24) {
50       throw new GeneralSecurityException("192 bit AES GCM Parameters are not valid");
51     }
52   }
53 
54   private static final PrimitiveConstructor<AesEaxKey, Aead> AES_EAX_PRIMITIVE_CONSTRUCTOR =
55       PrimitiveConstructor.create(AesEaxJce::create, AesEaxKey.class, Aead.class);
56 
getKeyType()57   static String getKeyType() {
58     return "type.googleapis.com/google.crypto.tink.AesEaxKey";
59   }
60 
61   private static final KeyManager<Aead> legacyKeyManager =
62       LegacyKeyManagerImpl.create(
63           getKeyType(),
64           Aead.class,
65           KeyMaterialType.SYMMETRIC,
66           com.google.crypto.tink.proto.AesEaxKey.parser());
67 
namedParameters()68   private static Map<String, Parameters> namedParameters() throws GeneralSecurityException {
69         Map<String, Parameters> result = new HashMap<>();
70         result.put("AES128_EAX", PredefinedAeadParameters.AES128_EAX);
71         result.put(
72             "AES128_EAX_RAW",
73             AesEaxParameters.builder()
74                 .setIvSizeBytes(16)
75                 .setKeySizeBytes(16)
76                 .setTagSizeBytes(16)
77                 .setVariant(AesEaxParameters.Variant.NO_PREFIX)
78                 .build());
79         result.put("AES256_EAX", PredefinedAeadParameters.AES256_EAX);
80         result.put(
81             "AES256_EAX_RAW",
82             AesEaxParameters.builder()
83                 .setIvSizeBytes(16)
84                 .setKeySizeBytes(32)
85                 .setTagSizeBytes(16)
86                 .setVariant(AesEaxParameters.Variant.NO_PREFIX)
87                 .build());
88 
89         return Collections.unmodifiableMap(result);
90   }
91 
92   @SuppressWarnings("InlineLambdaConstant") // We need a correct Object#equals in registration.
93   private static final MutableKeyCreationRegistry.KeyCreator<AesEaxParameters> KEY_CREATOR =
94       AesEaxKeyManager::createAesEaxKey;
95 
96   @AccessesPartialKey
createAesEaxKey( AesEaxParameters parameters, @Nullable Integer idRequirement)97   private static com.google.crypto.tink.aead.AesEaxKey createAesEaxKey(
98       AesEaxParameters parameters, @Nullable Integer idRequirement)
99       throws GeneralSecurityException {
100     validate(parameters);
101     return com.google.crypto.tink.aead.AesEaxKey.builder()
102         .setParameters(parameters)
103         .setIdRequirement(idRequirement)
104         .setKeyBytes(SecretBytes.randomBytes(parameters.getKeySizeBytes()))
105         .build();
106   }
107 
register(boolean newKeyAllowed)108   public static void register(boolean newKeyAllowed) throws GeneralSecurityException {
109     if (!TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_NOT_FIPS.isCompatible()) {
110       throw new GeneralSecurityException("Registering AES EAX is not supported in FIPS mode");
111     }
112     AesEaxProtoSerialization.register();
113     MutablePrimitiveRegistry.globalInstance()
114         .registerPrimitiveConstructor(AES_EAX_PRIMITIVE_CONSTRUCTOR);
115     MutableParametersRegistry.globalInstance().putAll(namedParameters());
116     MutableKeyCreationRegistry.globalInstance().add(KEY_CREATOR, AesEaxParameters.class);
117     KeyManagerRegistry.globalInstance().registerKeyManager(legacyKeyManager, newKeyAllowed);
118   }
119 
120   /**
121    * @return a {@link KeyTemplate} that generates new instances of AES-EAX with the following
122    *     parameters:
123    *     <ul>
124    *       <li>Key size: 16 bytes
125    *       <li>IV size: 16 bytes
126    *       <li>Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
127    *     </ul>
128    */
aes128EaxTemplate()129   public static final KeyTemplate aes128EaxTemplate() {
130     return exceptionIsBug(
131         () ->
132             KeyTemplate.createFrom(
133                 AesEaxParameters.builder()
134                     .setIvSizeBytes(16)
135                     .setKeySizeBytes(16)
136                     .setTagSizeBytes(16)
137                     .setVariant(AesEaxParameters.Variant.TINK)
138                     .build()));
139   }
140 
141   /**
142    * @return a {@link KeyTemplate} that generates new instances of AES-EAX with the following
143    *     parameters:
144    *     <ul>
145    *       <li>Key size: 16 bytes
146    *       <li>IV size: 16 bytes
147    *       <li>Prefix type: {@link KeyTemplate.OutputPrefixType#RAW} (no prefix)
148    *     </ul>
149    */
rawAes128EaxTemplate()150   public static final KeyTemplate rawAes128EaxTemplate() {
151     return exceptionIsBug(
152         () ->
153             KeyTemplate.createFrom(
154                 AesEaxParameters.builder()
155                     .setIvSizeBytes(16)
156                     .setKeySizeBytes(16)
157                     .setTagSizeBytes(16)
158                     .setVariant(AesEaxParameters.Variant.NO_PREFIX)
159                     .build()));
160   }
161 
162   /**
163    * @return a {@link KeyTemplate} that generates new instances of AES-EAX with the following
164    *     parameters:
165    *     <ul>
166    *       <li>Key size: 32 bytes
167    *       <li>IV size: 16 bytes
168    *       <li>Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
169    *     </ul>
170    */
aes256EaxTemplate()171   public static final KeyTemplate aes256EaxTemplate() {
172     return exceptionIsBug(
173         () ->
174             KeyTemplate.createFrom(
175                 AesEaxParameters.builder()
176                     .setIvSizeBytes(16)
177                     .setKeySizeBytes(32)
178                     .setTagSizeBytes(16)
179                     .setVariant(AesEaxParameters.Variant.TINK)
180                     .build()));
181   }
182 
183   /**
184    * @return a {@link KeyTemplate} that generates new instances of AES-EAX with the following
185    *     parameters:
186    *     <ul>
187    *       <li>Key size: 32 bytes
188    *       <li>IV size: 16 bytes
189    *       <li>Prefix type: {@link KeyTemplate.OutputPrefixType#RAW} (no prefix)
190    *     </ul>
191    */
rawAes256EaxTemplate()192   public static final KeyTemplate rawAes256EaxTemplate() {
193     return exceptionIsBug(
194         () ->
195             KeyTemplate.createFrom(
196                 AesEaxParameters.builder()
197                     .setIvSizeBytes(16)
198                     .setKeySizeBytes(32)
199                     .setTagSizeBytes(16)
200                     .setVariant(AesEaxParameters.Variant.NO_PREFIX)
201                     .build()));
202   }
203 
AesEaxKeyManager()204   private AesEaxKeyManager() {}
205 }
206