All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.google.crypto.tink.mac.HmacKeyManager Maven / Gradle / Ivy
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package com.google.crypto.tink.mac;
import static com.google.crypto.tink.internal.TinkBugException.exceptionIsBug;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.KeyTemplate;
import com.google.crypto.tink.Mac;
import com.google.crypto.tink.Parameters;
import com.google.crypto.tink.Registry;
import com.google.crypto.tink.SecretKeyAccess;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.crypto.tink.internal.KeyTypeManager;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.internal.PrimitiveConstructor;
import com.google.crypto.tink.internal.PrimitiveFactory;
import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.mac.internal.ChunkedHmacImpl;
import com.google.crypto.tink.mac.internal.HmacProtoSerialization;
import com.google.crypto.tink.proto.HashType;
import com.google.crypto.tink.proto.HmacKey;
import com.google.crypto.tink.proto.HmacKeyFormat;
import com.google.crypto.tink.proto.HmacParams;
import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
import com.google.crypto.tink.subtle.PrfHmacJce;
import com.google.crypto.tink.subtle.PrfMac;
import com.google.crypto.tink.subtle.Random;
import com.google.crypto.tink.subtle.Validators;
import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.InvalidProtocolBufferException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import javax.crypto.spec.SecretKeySpec;
/**
* This key manager generates new {@code HmacKey} keys and produces new instances of {@code
* PrfHmacJce}.
*/
public final class HmacKeyManager extends KeyTypeManager {
public HmacKeyManager() {
super(
HmacKey.class,
new PrimitiveFactory(Mac.class) {
@Override
public Mac getPrimitive(HmacKey key) throws GeneralSecurityException {
HashType hash = key.getParams().getHash();
byte[] keyValue = key.getKeyValue().toByteArray();
SecretKeySpec keySpec = new SecretKeySpec(keyValue, "HMAC");
int tagSize = key.getParams().getTagSize();
switch (hash) {
case SHA1:
return new PrfMac(new PrfHmacJce("HMACSHA1", keySpec), tagSize);
case SHA224:
return new PrfMac(new PrfHmacJce("HMACSHA224", keySpec), tagSize);
case SHA256:
return new PrfMac(new PrfHmacJce("HMACSHA256", keySpec), tagSize);
case SHA384:
return new PrfMac(new PrfHmacJce("HMACSHA384", keySpec), tagSize);
case SHA512:
return new PrfMac(new PrfHmacJce("HMACSHA512", keySpec), tagSize);
default:
throw new GeneralSecurityException("unknown hash");
}
}
});
}
/** Minimum key size in bytes. */
private static final int MIN_KEY_SIZE_IN_BYTES = 16;
/** Minimum tag size in bytes. This provides minimum 80-bit security strength. */
private static final int MIN_TAG_SIZE_IN_BYTES = 10;
private static final PrimitiveConstructor
CHUNKED_MAC_PRIMITIVE_CONSTRUCTOR =
PrimitiveConstructor.create(
ChunkedHmacImpl::new, com.google.crypto.tink.mac.HmacKey.class, ChunkedMac.class);
private static final PrimitiveConstructor
MAC_PRIMITIVE_CONSTRUCTOR =
PrimitiveConstructor.create(
PrfMac::create, com.google.crypto.tink.mac.HmacKey.class, Mac.class);
@Override
public String getKeyType() {
return "type.googleapis.com/google.crypto.tink.HmacKey";
}
@Override
public int getVersion() {
return 0;
}
@Override
public KeyMaterialType keyMaterialType() {
return KeyMaterialType.SYMMETRIC;
}
@Override
public void validateKey(HmacKey key) throws GeneralSecurityException {
Validators.validateVersion(key.getVersion(), getVersion());
if (key.getKeyValue().size() < MIN_KEY_SIZE_IN_BYTES) {
throw new GeneralSecurityException("key too short");
}
validateParams(key.getParams());
}
@Override
public HmacKey parseKey(ByteString byteString) throws InvalidProtocolBufferException {
return HmacKey.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry());
}
private static void validateParams(HmacParams params) throws GeneralSecurityException {
if (params.getTagSize() < MIN_TAG_SIZE_IN_BYTES) {
throw new GeneralSecurityException("tag size too small");
}
switch (params.getHash()) {
case SHA1:
if (params.getTagSize() > 20) {
throw new GeneralSecurityException("tag size too big");
}
break;
case SHA224:
if (params.getTagSize() > 28) {
throw new GeneralSecurityException("tag size too big");
}
break;
case SHA256:
if (params.getTagSize() > 32) {
throw new GeneralSecurityException("tag size too big");
}
break;
case SHA384:
if (params.getTagSize() > 48) {
throw new GeneralSecurityException("tag size too big");
}
break;
case SHA512:
if (params.getTagSize() > 64) {
throw new GeneralSecurityException("tag size too big");
}
break;
default:
throw new GeneralSecurityException("unknown hash type");
}
}
@Override
public KeyFactory keyFactory() {
return new KeyFactory(HmacKeyFormat.class) {
@Override
public void validateKeyFormat(HmacKeyFormat format) throws GeneralSecurityException {
if (format.getKeySize() < MIN_KEY_SIZE_IN_BYTES) {
throw new GeneralSecurityException("key too short");
}
validateParams(format.getParams());
}
@Override
public HmacKeyFormat parseKeyFormat(ByteString byteString)
throws InvalidProtocolBufferException {
return HmacKeyFormat.parseFrom(byteString, ExtensionRegistryLite.getEmptyRegistry());
}
@Override
public HmacKey createKey(HmacKeyFormat format) throws GeneralSecurityException {
return HmacKey.newBuilder()
.setVersion(getVersion())
.setParams(format.getParams())
.setKeyValue(ByteString.copyFrom(Random.randBytes(format.getKeySize())))
.build();
}
@Override
public com.google.crypto.tink.mac.HmacKey createKeyFromRandomness(
Parameters parameters,
InputStream stream,
@Nullable Integer idRequirement,
SecretKeyAccess access)
throws GeneralSecurityException {
if (parameters instanceof HmacParameters) {
return createHmacKeyFromRandomness(
(HmacParameters) parameters, stream, idRequirement, access);
}
throw new GeneralSecurityException(
"Unexpected parameters: expected HmacParameters, but got: " + parameters);
}
};
}
@AccessesPartialKey
static com.google.crypto.tink.mac.HmacKey createHmacKeyFromRandomness(
HmacParameters parameters,
InputStream stream,
@Nullable Integer idRequirement,
SecretKeyAccess access)
throws GeneralSecurityException {
return com.google.crypto.tink.mac.HmacKey.builder()
.setParameters(parameters)
.setKeyBytes(Util.readIntoSecretBytes(stream, parameters.getKeySizeBytes(), access))
.setIdRequirement(idRequirement)
.build();
}
private static Map namedParameters() throws GeneralSecurityException {
Map result = new HashMap<>();
result.put("HMAC_SHA256_128BITTAG", PredefinedMacParameters.HMAC_SHA256_128BITTAG);
result.put(
"HMAC_SHA256_128BITTAG_RAW",
HmacParameters.builder()
.setKeySizeBytes(32)
.setTagSizeBytes(16)
.setVariant(HmacParameters.Variant.NO_PREFIX)
.setHashType(HmacParameters.HashType.SHA256)
.build());
result.put(
"HMAC_SHA256_256BITTAG",
HmacParameters.builder()
.setKeySizeBytes(32)
.setTagSizeBytes(32)
.setVariant(HmacParameters.Variant.TINK)
.setHashType(HmacParameters.HashType.SHA256)
.build());
result.put(
"HMAC_SHA256_256BITTAG_RAW",
HmacParameters.builder()
.setKeySizeBytes(32)
.setTagSizeBytes(32)
.setVariant(HmacParameters.Variant.NO_PREFIX)
.setHashType(HmacParameters.HashType.SHA256)
.build());
result.put(
"HMAC_SHA512_128BITTAG",
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(16)
.setVariant(HmacParameters.Variant.TINK)
.setHashType(HmacParameters.HashType.SHA512)
.build());
result.put(
"HMAC_SHA512_128BITTAG_RAW",
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(16)
.setVariant(HmacParameters.Variant.NO_PREFIX)
.setHashType(HmacParameters.HashType.SHA512)
.build());
result.put(
"HMAC_SHA512_256BITTAG",
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(32)
.setVariant(HmacParameters.Variant.TINK)
.setHashType(HmacParameters.HashType.SHA512)
.build());
result.put(
"HMAC_SHA512_256BITTAG_RAW",
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(32)
.setVariant(HmacParameters.Variant.NO_PREFIX)
.setHashType(HmacParameters.HashType.SHA512)
.build());
result.put("HMAC_SHA512_512BITTAG", PredefinedMacParameters.HMAC_SHA512_512BITTAG);
result.put(
"HMAC_SHA512_512BITTAG_RAW",
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(64)
.setVariant(HmacParameters.Variant.NO_PREFIX)
.setHashType(HmacParameters.HashType.SHA512)
.build());
return Collections.unmodifiableMap(result);
}
public static void register(boolean newKeyAllowed) throws GeneralSecurityException {
Registry.registerKeyManager(new HmacKeyManager(), newKeyAllowed);
HmacProtoSerialization.register();
MutablePrimitiveRegistry.globalInstance()
.registerPrimitiveConstructor(CHUNKED_MAC_PRIMITIVE_CONSTRUCTOR);
MutablePrimitiveRegistry.globalInstance()
.registerPrimitiveConstructor(MAC_PRIMITIVE_CONSTRUCTOR);
MutableParametersRegistry.globalInstance().putAll(namedParameters());
}
/**
* @return A {@link KeyTemplate} that generates new instances of HMAC keys with the following
* parameters:
*
* Key size: 32 bytes
* Tag size: 16 bytes
* Hash function: SHA256
* Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
*
*/
public static final KeyTemplate hmacSha256HalfDigestTemplate() {
return exceptionIsBug(
() ->
KeyTemplate.createFrom(
HmacParameters.builder()
.setKeySizeBytes(32)
.setTagSizeBytes(16)
.setHashType(HmacParameters.HashType.SHA256)
.setVariant(HmacParameters.Variant.TINK)
.build()));
}
/**
* @return A {@link KeyTemplate} that generates new instances of HMAC keys with the following
* parameters:
*
* Key size: 32 bytes
* Tag size: 32 bytes
* Hash function: SHA256
* Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
*
*/
public static final KeyTemplate hmacSha256Template() {
return exceptionIsBug(
() ->
KeyTemplate.createFrom(
HmacParameters.builder()
.setKeySizeBytes(32)
.setTagSizeBytes(32)
.setHashType(HmacParameters.HashType.SHA256)
.setVariant(HmacParameters.Variant.TINK)
.build()));
}
/**
* @return A {@link KeyTemplate} that generates new instances of HMAC keys with the following
* parameters:
*
* Key size: 64 bytes
* Tag size: 32 bytes
* Hash function: SHA512
* Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
*
*/
public static final KeyTemplate hmacSha512HalfDigestTemplate() {
return exceptionIsBug(
() ->
KeyTemplate.createFrom(
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(32)
.setHashType(HmacParameters.HashType.SHA512)
.setVariant(HmacParameters.Variant.TINK)
.build()));
}
/**
* @return A {@link KeyTemplate} that generates new instances of HMAC keys with the following
* parameters:
*
* Key size: 64 bytes
* Tag size: 64 bytes
* Hash function: SHA512
* Prefix type: {@link KeyTemplate.OutputPrefixType#TINK}
*
*/
public static final KeyTemplate hmacSha512Template() {
return exceptionIsBug(
() ->
KeyTemplate.createFrom(
HmacParameters.builder()
.setKeySizeBytes(64)
.setTagSizeBytes(64)
.setHashType(HmacParameters.HashType.SHA512)
.setVariant(HmacParameters.Variant.TINK)
.build()));
}
@Override
public TinkFipsUtil.AlgorithmFipsCompatibility fipsStatus() {
return TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO;
}
}