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.AccessesPartialKey; 20 import com.google.crypto.tink.Key; 21 import com.google.crypto.tink.util.SecretBytes; 22 import com.google.errorprone.annotations.CanIgnoreReturnValue; 23 import com.google.errorprone.annotations.Immutable; 24 import com.google.errorprone.annotations.RestrictedApi; 25 import java.security.GeneralSecurityException; 26 import javax.annotation.Nullable; 27 28 /** Represents a key computing HMAC PRF. */ 29 @Immutable 30 public final class HmacPrfKey extends PrfKey { 31 private final HmacPrfParameters parameters; 32 private final SecretBytes keyBytes; 33 34 /** Builder for HmacPrfKey. */ 35 public static final class Builder { 36 @Nullable private HmacPrfParameters parameters = null; 37 @Nullable private SecretBytes keyBytes = null; 38 Builder()39 private Builder() {} 40 41 @CanIgnoreReturnValue setParameters(HmacPrfParameters parameters)42 public Builder setParameters(HmacPrfParameters parameters) { 43 this.parameters = parameters; 44 return this; 45 } 46 47 @CanIgnoreReturnValue setKeyBytes(SecretBytes keyBytes)48 public Builder setKeyBytes(SecretBytes keyBytes) { 49 this.keyBytes = keyBytes; 50 return this; 51 } 52 build()53 public HmacPrfKey build() throws GeneralSecurityException { 54 if (parameters == null || keyBytes == null) { 55 throw new GeneralSecurityException("Cannot build without parameters and/or key material"); 56 } 57 58 if (parameters.getKeySizeBytes() != keyBytes.size()) { 59 throw new GeneralSecurityException("Key size mismatch"); 60 } 61 62 return new HmacPrfKey(parameters, keyBytes); 63 } 64 } 65 HmacPrfKey(HmacPrfParameters parameters, SecretBytes keyBytes)66 private HmacPrfKey(HmacPrfParameters parameters, SecretBytes keyBytes) { 67 this.parameters = parameters; 68 this.keyBytes = keyBytes; 69 } 70 71 @RestrictedApi( 72 explanation = "Accessing parts of keys can produce unexpected incompatibilities, annotate the function with @AccessesPartialKey", 73 link = "https://developers.google.com/tink/design/access_control#accessing_partial_keys", 74 allowedOnPath = ".*Test\\.java", 75 allowlistAnnotations = {AccessesPartialKey.class}) builder()76 public static Builder builder() { 77 return new Builder(); 78 } 79 80 @RestrictedApi( 81 explanation = "Accessing parts of keys can produce unexpected incompatibilities, annotate the function with @AccessesPartialKey", 82 link = "https://developers.google.com/tink/design/access_control#accessing_partial_keys", 83 allowedOnPath = ".*Test\\.java", 84 allowlistAnnotations = {AccessesPartialKey.class}) getKeyBytes()85 public SecretBytes getKeyBytes() { 86 return keyBytes; 87 } 88 89 @Override getParameters()90 public HmacPrfParameters getParameters() { 91 return parameters; 92 } 93 94 @Override 95 @Nullable getIdRequirementOrNull()96 public Integer getIdRequirementOrNull() { 97 return null; 98 } 99 100 @Override equalsKey(Key o)101 public boolean equalsKey(Key o) { 102 if (!(o instanceof HmacPrfKey)) { 103 return false; 104 } 105 HmacPrfKey that = (HmacPrfKey) o; 106 return that.parameters.equals(parameters) && that.keyBytes.equalsSecretBytes(keyBytes); 107 } 108 } 109