From ab4f1364a2bbb3d1a93c274643de5c5d9fd238ac Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 7 Apr 2022 21:10:40 +0200 Subject: [PATCH] Start adding support for preferred AEAD algorithms --- .../pgpainless/algorithm/AEADAlgorithm.java | 57 +++++++++++++++++++ .../algorithm/AEADCipherSuitePair.java | 56 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java create mode 100644 pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADCipherSuitePair.java diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java b/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java new file mode 100644 index 00000000..6fc69799 --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.algorithm; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.NoSuchElementException; + +public enum AEADAlgorithm { + + EAX(1, 16, 16), + OCB(2, 15, 16), + GCM(3, 12, 16), + ; + + private static final Map MAP = new HashMap<>(); + + private final int id; + private final int ivLen; + private final int tagLen; + + AEADAlgorithm(int id, int ivLen, int tagLen) { + this.id = id; + this.ivLen = ivLen; + this.tagLen = tagLen; + } + + @Nullable + public static AEADAlgorithm fromId(int algorithmId) { + return MAP.get(algorithmId); + } + + @Nonnull + public static AEADAlgorithm requireFromId(int algorithmId) { + AEADAlgorithm algorithm = fromId(algorithmId); + if (algorithm == null) { + throw new NoSuchElementException("No AEAD Algorithm found for id " + algorithmId); + } + return algorithm; + } + + public int getAlgorithmId() { + return id; + } + + public int getIvLength() { + return ivLen; + } + + public int getTagLength() { + return tagLen; + } +} diff --git a/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADCipherSuitePair.java b/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADCipherSuitePair.java new file mode 100644 index 00000000..ca635d3c --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADCipherSuitePair.java @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.algorithm; + +import javax.annotation.Nonnull; + +public class AEADCipherSuitePair { + + private final AEADAlgorithm aeadAlgorithm; + private final SymmetricKeyAlgorithm symmetricKeyAlgorithm; + + public AEADCipherSuitePair(@Nonnull SymmetricKeyAlgorithm symmetric, @Nonnull AEADAlgorithm aead) { + this.symmetricKeyAlgorithm = symmetric; + this.aeadAlgorithm = aead; + } + + public SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() { + return symmetricKeyAlgorithm; + } + + public AEADAlgorithm getAeadAlgorithm() { + return aeadAlgorithm; + } + + /** + * Mandatory-to-implement combination of AES-128 and OCB + * + * @return algorithm pair for AES-128 and OCB + */ + public static AEADCipherSuitePair aes128WithOcb() { + return new AEADCipherSuitePair(SymmetricKeyAlgorithm.AES_128, AEADAlgorithm.OCB); + } + + @Override + public int hashCode() { + return symmetricKeyAlgorithm.hashCode() * 31 + aeadAlgorithm.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (this == obj) { + return true; + } + if (!(obj instanceof AEADCipherSuitePair)) { + return false; + } + AEADCipherSuitePair other = (AEADCipherSuitePair) obj; + return getAeadAlgorithm() == other.getAeadAlgorithm() + && getSymmetricKeyAlgorithm() == other.getSymmetricKeyAlgorithm(); + } +}