From cd5982cd478818ca374eaa7eb3a600d21e8bdf32 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Mon, 18 Jul 2022 11:30:37 +0200 Subject: [PATCH] Add AEADAlgorithm class and test --- .../pgpainless/algorithm/AEADAlgorithm.java | 95 +++++++++++++++++++ .../algorithm/AEADAlgorithmTest.java | 50 ++++++++++ 2 files changed, 145 insertions(+) create mode 100644 pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java create mode 100644 pgpainless-core/src/test/java/org/pgpainless/algorithm/AEADAlgorithmTest.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..106d6bff --- /dev/null +++ b/pgpainless-core/src/main/java/org/pgpainless/algorithm/AEADAlgorithm.java @@ -0,0 +1,95 @@ +// 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; + +/** + * List of AEAD algorithms defined in crypto-refresh-06. + * + * @see + * Crypto-Refresh-06 ยง9.6 - AEAD Algorithms + */ +public enum AEADAlgorithm { + + EAX(1, 16, 16), + OCB(2, 15, 16), + GCM(3, 12, 16), + ; + + private final int algorithmId; + private final int ivLength; + private final int tagLength; + + private static final Map MAP = new HashMap<>(); + + static { + for (AEADAlgorithm h : AEADAlgorithm.values()) { + MAP.put(h.algorithmId, h); + } + } + + AEADAlgorithm(int id, int ivLength, int tagLength) { + this.algorithmId = id; + this.ivLength = ivLength; + this.tagLength = tagLength; + } + + public int getAlgorithmId() { + return algorithmId; + } + + /** + * Return the length (in octets) of the IV. + * + * @return iv length + */ + public int getIvLength() { + return ivLength; + } + + /** + * Return the length (in octets) of the authentication tag. + * + * @return tag length + */ + public int getTagLength() { + return tagLength; + } + + /** + * Return the {@link AEADAlgorithm} value that corresponds to the provided algorithm id. + * If an invalid algorithm id was provided, null is returned. + * + * @param id numeric id + * @return enum value + */ + @Nullable + public static AEADAlgorithm fromId(int id) { + return MAP.get(id); + } + + /** + * Return the {@link AEADAlgorithm} value that corresponds to the provided algorithm id. + * If an invalid algorithm id was provided, throw a {@link NoSuchElementException}. + * + * @param id algorithm id + * @return enum value + * @throws NoSuchElementException in case of an unknown algorithm id + */ + @Nonnull + public static AEADAlgorithm requireFromId(int id) { + AEADAlgorithm algorithm = fromId(id); + if (algorithm == null) { + throw new NoSuchElementException("No AEADAlgorithm found for id " + id); + } + return algorithm; + } + +} diff --git a/pgpainless-core/src/test/java/org/pgpainless/algorithm/AEADAlgorithmTest.java b/pgpainless-core/src/test/java/org/pgpainless/algorithm/AEADAlgorithmTest.java new file mode 100644 index 00000000..58423190 --- /dev/null +++ b/pgpainless-core/src/test/java/org/pgpainless/algorithm/AEADAlgorithmTest.java @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2022 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.algorithm; + +import org.junit.jupiter.api.Test; + +import java.util.NoSuchElementException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class AEADAlgorithmTest { + + @Test + public void testEAXParameters() { + AEADAlgorithm eax = AEADAlgorithm.EAX; + assertEquals(1, eax.getAlgorithmId()); + assertEquals(16, eax.getIvLength()); + assertEquals(16, eax.getTagLength()); + } + + @Test + public void testOCBParameters() { + AEADAlgorithm ocb = AEADAlgorithm.OCB; + assertEquals(2, ocb.getAlgorithmId()); + assertEquals(15, ocb.getIvLength()); + assertEquals(16, ocb.getTagLength()); + } + + @Test + public void testGCMParameters() { + AEADAlgorithm gcm = AEADAlgorithm.GCM; + assertEquals(3, gcm.getAlgorithmId()); + assertEquals(12, gcm.getIvLength()); + assertEquals(16, gcm.getTagLength()); + } + + @Test + public void testFromId() { + assertEquals(AEADAlgorithm.EAX, AEADAlgorithm.requireFromId(1)); + assertEquals(AEADAlgorithm.OCB, AEADAlgorithm.requireFromId(2)); + assertEquals(AEADAlgorithm.GCM, AEADAlgorithm.requireFromId(3)); + + assertNull(AEADAlgorithm.fromId(99)); + assertThrows(NoSuchElementException.class, () -> AEADAlgorithm.requireFromId(99)); + } +}