• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
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.prf;
18 
19 import com.google.crypto.tink.util.Bytes;
20 import com.google.errorprone.annotations.CanIgnoreReturnValue;
21 import com.google.errorprone.annotations.Immutable;
22 import java.security.GeneralSecurityException;
23 import java.security.InvalidAlgorithmParameterException;
24 import java.util.Objects;
25 import javax.annotation.Nullable;
26 
27 /** Describes the parameters of an {@link HkdfPrfKey}. */
28 public final class HkdfPrfParameters extends PrfParameters {
29   private static final int MIN_KEY_SIZE = 16;
30 
31   /** The Hash algorithm used. */
32   @Immutable
33   public static final class HashType {
34     public static final HashType SHA1 = new HashType("SHA1");
35     public static final HashType SHA224 = new HashType("SHA224");
36     public static final HashType SHA256 = new HashType("SHA256");
37     public static final HashType SHA384 = new HashType("SHA384");
38     public static final HashType SHA512 = new HashType("SHA512");
39 
40     private final String name;
41 
HashType(String name)42     private HashType(String name) {
43       this.name = name;
44     }
45 
46     @Override
toString()47     public String toString() {
48       return name;
49     }
50   }
51 
52   /** Builder for HkdfPrfParameters. */
53   public static final class Builder {
54     @Nullable private Integer keySizeBytes = null;
55     @Nullable private HashType hashType = null;
56     @Nullable private Bytes salt = null;
57 
Builder()58     private Builder() {}
59 
60     @CanIgnoreReturnValue
setKeySizeBytes(int keySizeBytes)61     public Builder setKeySizeBytes(int keySizeBytes) throws GeneralSecurityException {
62       if (keySizeBytes < MIN_KEY_SIZE) {
63         throw new InvalidAlgorithmParameterException(
64             String.format(
65                 "Invalid key size %d; only 128-bit or larger are supported", keySizeBytes * 8));
66       }
67       this.keySizeBytes = keySizeBytes;
68       return this;
69     }
70 
71     @CanIgnoreReturnValue
setHashType(HashType hashType)72     public Builder setHashType(HashType hashType) {
73       this.hashType = hashType;
74       return this;
75     }
76 
77     @CanIgnoreReturnValue
setSalt(Bytes salt)78     public Builder setSalt(Bytes salt) {
79       if (salt.size() == 0) {
80         this.salt = null;
81         return this;
82       }
83       this.salt = salt;
84       return this;
85     }
86 
build()87     public HkdfPrfParameters build() throws GeneralSecurityException {
88       if (keySizeBytes == null) {
89         throw new GeneralSecurityException("key size is not set");
90       }
91       if (hashType == null) {
92         throw new GeneralSecurityException("hash type is not set");
93       }
94       return new HkdfPrfParameters(keySizeBytes, hashType, salt);
95     }
96   }
97 
98   private final int keySizeBytes;
99   private final HashType hashType;
100   @Nullable private final Bytes salt;
101 
HkdfPrfParameters(int keySizeBytes, HashType hashType, Bytes salt)102   private HkdfPrfParameters(int keySizeBytes, HashType hashType, Bytes salt) {
103     this.keySizeBytes = keySizeBytes;
104     this.hashType = hashType;
105     this.salt = salt;
106   }
107 
builder()108   public static Builder builder() {
109     return new Builder();
110   }
111 
getKeySizeBytes()112   public int getKeySizeBytes() {
113     return keySizeBytes;
114   }
115 
getHashType()116   public HashType getHashType() {
117     return hashType;
118   }
119 
120   /**
121    * Gets the salt value, which defaults to null if not set, as per RFC 5869. The HKDF PRF
122    * implementation must convert a null salt to a string of zeros that is the length of the hash
123    * function output.
124    */
125   @Nullable
getSalt()126   public Bytes getSalt() {
127     return salt;
128   }
129 
130   @Override
equals(Object o)131   public boolean equals(Object o) {
132     if (!(o instanceof HkdfPrfParameters)) {
133       return false;
134     }
135     HkdfPrfParameters that = (HkdfPrfParameters) o;
136     return that.getKeySizeBytes() == getKeySizeBytes()
137         && that.getHashType() == getHashType()
138         && Objects.equals(that.getSalt(), getSalt());
139   }
140 
141   @Override
hashCode()142   public int hashCode() {
143     return Objects.hash(HkdfPrfParameters.class, keySizeBytes, hashType, salt);
144   }
145 
146   @Override
hasIdRequirement()147   public boolean hasIdRequirement() {
148     return false;
149   }
150 
151   @Override
toString()152   public String toString() {
153     return "HKDF PRF Parameters (hashType: "
154         + hashType
155         + ", salt: "
156         + salt
157         + ", and "
158         + keySizeBytes
159         + "-byte key)";
160   }
161 }
162