Skip to content

Commit

Permalink
Model update (#126)
Browse files Browse the repository at this point in the history
* fix some PublicKeyEncryption in model

Signed-off-by: Hugo Queinnec <[email protected]>

* update Kyber/ML-KEM

Signed-off-by: Hugo Queinnec <[email protected]>

* fix TODO

Signed-off-by: Hugo Queinnec <[email protected]>

* shake parameterSetIdentifier

Signed-off-by: Hugo Queinnec <[email protected]>

---------

Signed-off-by: Hugo Queinnec <[email protected]>
  • Loading branch information
hugoqnc authored Sep 3, 2024
1 parent 7452945 commit 31cd635
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private BcEncapsulatedSecretExtractor() {
// nothing
}

/* TODO: maybe the function `extractSecret` would be a better entry point than the constructors? */
/* TODO: capture the `AsymmetricKeyParameter` argument in most contructors */

private static BouncyCastleInfoMap infoMap = new BouncyCastleInfoMap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private BcEncapsulatedSecretGenerator() {
// nothing
}

/* TODO: maybe the function `generateEncapsulated` would be a better entry point than the constructors? */
/* TODO: capture `generateEncapsulated` to obtain information from `AsymmetricKeyParameter` */

private static BouncyCastleInfoMap infoMap = new BouncyCastleInfoMap();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,8 @@ public final class JavaCipherContextTranslator extends JavaAbstractLibraryTransl
.parse(valueAction.asString(), detectionLocation)
.map(f -> f);
case ASYMMETRIC_CIPHER_ENGINE, ASYMMETRIC_CIPHER_ENGINE_SIGNATURE:
/* TODO: the Signature distinction (and therefore the asKind parameter of the mapper) does not seem necessary */
BcAsymCipherEngineMapper bcAsymCipherEngineMapper =
new BcAsymCipherEngineMapper(PublicKeyEncryption.class);
new BcAsymCipherEngineMapper();
return bcAsymCipherEngineMapper
.parse(valueAction.asString(), detectionLocation)
.map(f -> f);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@

import com.ibm.mapper.mapper.IMapper;
import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.BlockCipher;
import com.ibm.mapper.model.IAlgorithm;
import com.ibm.mapper.model.INode;
import com.ibm.mapper.model.IPrimitive;
import com.ibm.mapper.model.PublicKeyEncryption;
import com.ibm.mapper.model.Unknown;
import com.ibm.mapper.model.algorithms.ElGamal;
import com.ibm.mapper.model.algorithms.NaccacheStern;
Expand All @@ -37,25 +35,14 @@

public class BcAsymCipherEngineMapper implements IMapper {

private final Class<? extends IPrimitive> asKind;

public BcAsymCipherEngineMapper(Class<? extends IPrimitive> asKind) {
this.asKind = asKind;
}

@Override
@Nonnull
public Optional<? extends INode> parse(
@Nullable String str, @Nonnull DetectionLocation detectionLocation) {
if (str == null) {
return Optional.empty();
}
Optional<? extends INode> node = map(str, detectionLocation);
if (node.isPresent()) {
// TODO: Change this to not use the `new Algorithm` hack to change the kind
return Optional.of(new Algorithm((IAlgorithm) node.get(), asKind));
}
return Optional.empty();
return map(str, detectionLocation);
}

@Nonnull
Expand All @@ -70,7 +57,7 @@ private Optional<? extends INode> map(
case "RSAEngine" -> Optional.of(new RSA(detectionLocation));
default -> {
final Algorithm algorithm =
new Algorithm(cipherString, BlockCipher.class, detectionLocation);
new Algorithm(cipherString, PublicKeyEncryption.class, detectionLocation);
algorithm.put(new Unknown(detectionLocation));
yield Optional.of(algorithm);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
import com.ibm.mapper.model.algorithms.ECIES;
import com.ibm.mapper.model.algorithms.FrodoKEM;
import com.ibm.mapper.model.algorithms.HQC;
import com.ibm.mapper.model.algorithms.MLKEM;
import com.ibm.mapper.model.algorithms.RSAKEM;
import com.ibm.mapper.model.algorithms.SABER;
import com.ibm.mapper.model.algorithms.kyber.Kyber;
import com.ibm.mapper.model.algorithms.ntru.NTRU;
import com.ibm.mapper.model.algorithms.ntru.NTRULPrime;
import com.ibm.mapper.model.algorithms.ntru.StreamlinedNTRUPrime;
Expand Down Expand Up @@ -66,7 +66,7 @@ private Optional<? extends INode> map(
case "HQCKEMExtractor", "HQCKEMGenerator" ->
Optional.of(new HQC(KeyEncapsulationMechanism.class, detectionLocation));
case "KyberKEMExtractor", "KyberKEMGenerator" ->
Optional.of(new MLKEM(detectionLocation));
Optional.of(new Kyber(detectionLocation));
case "NTRUKEMExtractor", "NTRUKEMGenerator" -> Optional.of(new NTRU(detectionLocation));
case "NTRULPRimeKEMExtractor", "NTRULPRimeKEMGenerator" ->
Optional.of(new NTRULPrime(detectionLocation));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public final class PycaDigestMapper implements IMapper {
case "SHA3_256" -> Optional.of(new SHA3(256, detectionLocation));
case "SHA3_384" -> Optional.of(new SHA3(384, detectionLocation));
case "SHA3_512" -> Optional.of(new SHA3(512, detectionLocation));
case "SHAKE128", "SHAKE256" -> Optional.of(new SHAKE(detectionLocation));
case "SHAKE128" -> Optional.of(new SHAKE(128, detectionLocation));
case "SHAKE256" -> Optional.of(new SHAKE(256, detectionLocation));
case "MD5" -> Optional.of(new MD5(detectionLocation));
case "BLAKE2B" -> Optional.of(new BLAKE2b(false, detectionLocation));
case "BLAKE2S" -> Optional.of(new BLAKE2s(false, detectionLocation));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,16 @@ public final class PycaHashBasedKeyDerivationMapper implements IMapper {
Optional.of(
new SHA3(
KeyDerivationFunction.class, new SHA3(512, detectionLocation)));
case "SHAKE128", "SHAKE256" ->
case "SHAKE128" ->
Optional.of(
new SHAKE(KeyDerivationFunction.class, new SHAKE(detectionLocation)));
new SHAKE(
KeyDerivationFunction.class,
new SHAKE(128, detectionLocation)));
case "SHAKE256" ->
Optional.of(
new SHAKE(
KeyDerivationFunction.class,
new SHAKE(256, detectionLocation)));
case "MD5" -> Optional.of(new MD5(Mac.class, detectionLocation));
case "BLAKE2B" ->
Optional.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ public class PycaMacMapper implements IMapper {
case "SHA3_256" -> Optional.of(new SHA3(Mac.class, new SHA3(256, detectionLocation)));
case "SHA3_384" -> Optional.of(new SHA3(Mac.class, new SHA3(384, detectionLocation)));
case "SHA3_512" -> Optional.of(new SHA3(Mac.class, new SHA3(512, detectionLocation)));
case "SHAKE128", "SHAKE256" ->
Optional.of(new SHAKE(Mac.class, new SHAKE(detectionLocation)));
case "SHAKE128" -> Optional.of(new SHAKE(Mac.class, new SHAKE(128, detectionLocation)));
case "SHAKE256" -> Optional.of(new SHAKE(Mac.class, new SHAKE(256, detectionLocation)));
case "MD5" -> Optional.of(new MD5(Mac.class, detectionLocation));
case "BLAKE2B" ->
Optional.of(new BLAKE2b(Mac.class, new BLAKE2b(false, detectionLocation)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public final class Ed448 extends EdDSA implements Signature {
public Ed448(@NotNull DetectionLocation detectionLocation) {
super(NAME, detectionLocation);
this.put(new Edwards448(detectionLocation));
this.put(new SHAKE(detectionLocation));
this.put(new SHAKE(256, detectionLocation));
this.put(new Oid("1.3.101.113", detectionLocation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@
package com.ibm.mapper.model.algorithms;

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.BlockCipher;
import com.ibm.mapper.model.IPrimitive;
import com.ibm.mapper.model.KeyLength;
import com.ibm.mapper.model.PublicKeyEncryption;
import com.ibm.mapper.model.Signature;
import com.ibm.mapper.utils.DetectionLocation;
import javax.annotation.Nonnull;

public final class ElGamal extends Algorithm implements BlockCipher, Signature {
public final class ElGamal extends Algorithm implements PublicKeyEncryption, Signature {
// https://en.wikipedia.org/wiki/ElGamal_encryption
// https://en.wikipedia.org/wiki/ElGamal_signature_scheme

private static final String NAME = "ElGamal";

public ElGamal(@Nonnull DetectionLocation detectionLocation) {
super(NAME, BlockCipher.class, detectionLocation);
super(NAME, PublicKeyEncryption.class, detectionLocation);
}

public ElGamal(int keyLength, @Nonnull DetectionLocation detectionLocation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
package com.ibm.mapper.model.algorithms;

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.BlockCipher;
import com.ibm.mapper.model.IPrimitive;
import com.ibm.mapper.model.KeyLength;
import com.ibm.mapper.model.PublicKeyEncryption;
import com.ibm.mapper.utils.DetectionLocation;
import javax.annotation.Nonnull;

public final class NaccacheStern extends Algorithm implements BlockCipher {
public final class NaccacheStern extends Algorithm implements PublicKeyEncryption {
// https://en.wikipedia.org/wiki/Naccache–Stern_cryptosystem

private static final String NAME = "Naccache-Stern";

public NaccacheStern(@Nonnull DetectionLocation detectionLocation) {
super(NAME, BlockCipher.class, detectionLocation);
super(NAME, PublicKeyEncryption.class, detectionLocation);
}

public NaccacheStern(int keyLength, @Nonnull DetectionLocation detectionLocation) {
Expand Down
25 changes: 25 additions & 0 deletions mapper/src/main/java/com/ibm/mapper/model/algorithms/SHAKE.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.ExtendableOutputFunction;
import com.ibm.mapper.model.INode;
import com.ibm.mapper.model.IPrimitive;
import com.ibm.mapper.model.ParameterSetIdentifier;
import com.ibm.mapper.utils.DetectionLocation;
import java.util.Optional;
import javax.annotation.Nonnull;

public final class SHAKE extends Algorithm implements ExtendableOutputFunction {
Expand All @@ -32,6 +35,28 @@ public SHAKE(@Nonnull DetectionLocation detectionLocation) {
super(NAME, ExtendableOutputFunction.class, detectionLocation);
}

/** Returns a name of the form "SHAKEXXX" where XXX is the parameter set identifer */
@Override
@Nonnull
public String getName() {
StringBuilder builtName = new StringBuilder(this.name);

Optional<INode> parameterSetIdentifier = this.hasChildOfType(ParameterSetIdentifier.class);

if (parameterSetIdentifier.isPresent()) {
builtName.append(parameterSetIdentifier.get().asString());
}

return builtName.toString();
}

public SHAKE(int parameterSetIdentifier, @Nonnull DetectionLocation detectionLocation) {
this(detectionLocation);
this.put(
new ParameterSetIdentifier(
String.valueOf(parameterSetIdentifier), detectionLocation));
}

public SHAKE(@Nonnull final Class<? extends IPrimitive> asKind, @Nonnull SHAKE shake) {
super(shake, asKind);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* SonarQube Cryptography Plugin
* Copyright (C) 2024 IBM
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you 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.ibm.mapper.model.algorithms.kyber;

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.INode;
import com.ibm.mapper.model.KeyEncapsulationMechanism;
import com.ibm.mapper.model.ParameterSetIdentifier;
import com.ibm.mapper.model.Version;
import com.ibm.mapper.utils.DetectionLocation;
import java.util.Optional;
import javax.annotation.Nonnull;

public class Kyber extends Algorithm implements KeyEncapsulationMechanism {
// https://pq-crystals.org/kyber/resources.shtml (details the multiple versions)
// https://en.wikipedia.org/wiki/Kyber

private static final String NAME = "Kyber"; // this is *not* ML-KEM

/**
* Returns a name of the form "Kyber-XXX (version YYY)" where XXX is the parameter set identifer
* and YYY the submission version
*/
@Override
@Nonnull
public String getName() {
StringBuilder builtName = new StringBuilder(this.name);

Optional<INode> parameterSetIdentifier = this.hasChildOfType(ParameterSetIdentifier.class);
Optional<INode> version = this.hasChildOfType(Version.class);

if (parameterSetIdentifier.isPresent()) {
builtName.append("-").append(parameterSetIdentifier.get().asString());
}
if (version.isPresent()) {
builtName.append(" (version ").append(version.get().asString()).append(")");
}

return builtName.toString();
}

public Kyber(@Nonnull DetectionLocation detectionLocation) {
super(NAME, KeyEncapsulationMechanism.class, detectionLocation);
}

public Kyber(int parameterSetIdentifier, @Nonnull DetectionLocation detectionLocation) {
this(detectionLocation);
this.put(
new ParameterSetIdentifier(
String.valueOf(parameterSetIdentifier), detectionLocation));
}

public Kyber(
@Nonnull String submissionVersionNumber, @Nonnull DetectionLocation detectionLocation) {
this(detectionLocation);
this.put(new Version(submissionVersionNumber, detectionLocation));
}

public Kyber(
int parameterSetIdentifier,
@Nonnull String submissionVersionNumber,
@Nonnull DetectionLocation detectionLocation) {
this(parameterSetIdentifier, detectionLocation);
this.put(new Version(submissionVersionNumber, detectionLocation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,45 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.mapper.model.algorithms;
package com.ibm.mapper.model.algorithms.kyber;

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.INode;
import com.ibm.mapper.model.KeyEncapsulationMechanism;
import com.ibm.mapper.model.ParameterSetIdentifier;
import com.ibm.mapper.utils.DetectionLocation;
import java.util.Optional;
import javax.annotation.Nonnull;

public class MLKEM extends Algorithm implements KeyEncapsulationMechanism {
// https://en.wikipedia.org/wiki/Kyber
// https://pq-crystals.org/kyber/
// https://csrc.nist.gov/pubs/fips/203/final
// This is the standardized version of Kyber

private static final String NAME =
"ML-KEM"; // Kyber, Module-Lattice-Based Key-Encapsulation Mechanism
private static final String NAME = "ML-KEM"; // Module-Lattice-Based Key-Encapsulation Mechanism

/** Returns a name of the form "ML-KEM-XXX" where XXX is the parameter set identifer */
@Override
@Nonnull
public String getName() {
StringBuilder builtName = new StringBuilder(this.name);

Optional<INode> parameterSetIdentifier = this.hasChildOfType(ParameterSetIdentifier.class);

if (parameterSetIdentifier.isPresent()) {
builtName.append("-").append(parameterSetIdentifier.get().asString());
}

return builtName.toString();
}

public MLKEM(@Nonnull DetectionLocation detectionLocation) {
super(NAME, KeyEncapsulationMechanism.class, detectionLocation);
}

public MLKEM(int parameterSetIdentifier, @Nonnull DetectionLocation detectionLocation) {
this(detectionLocation);
this.put(
new ParameterSetIdentifier(
String.valueOf(parameterSetIdentifier), detectionLocation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@
package com.ibm.mapper.model.algorithms.ntru;

import com.ibm.mapper.model.Algorithm;
import com.ibm.mapper.model.BlockCipher;
import com.ibm.mapper.model.IPrimitive;
import com.ibm.mapper.model.KeyLength;
import com.ibm.mapper.model.PublicKeyEncryption;
import com.ibm.mapper.utils.DetectionLocation;
import javax.annotation.Nonnull;

public final class NTRUEncrypt extends Algorithm implements BlockCipher {
public final class NTRUEncrypt extends Algorithm implements PublicKeyEncryption {
// https://en.wikipedia.org/wiki/NTRU

private static final String NAME = "NTRUEncrypt";

public NTRUEncrypt(@Nonnull DetectionLocation detectionLocation) {
super(NAME, BlockCipher.class, detectionLocation);
super(NAME, PublicKeyEncryption.class, detectionLocation);
}

public NTRUEncrypt(int keyLength, @Nonnull DetectionLocation detectionLocation) {
Expand Down

0 comments on commit 31cd635

Please sign in to comment.