On Tue, 2 May 2023 21:43:19 GMT, Ferenc Rakoczi <d...@openjdk.org> wrote:
>> Implement support for Leighton-Micali Signatures (LMS) as described in RFC >> 8554. LMS is an approved software signing algorithm for CNSA 2.0, with >> SHA-256/192 parameters recommended. > > Ferenc Rakoczi has updated the pull request incrementally with one additional > commit since the last revision: > > adding key translation, finally block, removing 24-byte LMOTS parameters src/java.base/share/classes/sun/security/provider/HSS.java line 94: > 92: result &= lmsVerify(lmsPubKey, sig.siglist[sig.Nspk], > messageStream.toByteArray()); > 93: return result; > 94: } catch (Exception e) { If all exceptions thrown are already `SignatureException`, we can let them thrown out instead of returning false. According to the `engineVerify` spec, any problem inside the signature should throw a `SignatureException`. False is returned when the public key cannot verify the exception. src/java.base/share/classes/sun/security/provider/HSS.java line 181: > 179: try { > 180: lmParams = new LMParams(type); > 181: lmotsParams = LMOTSParams.of(otsType); Try to code `LMParams` and `LMOTSParams` the same style by choosing from using a constructor or static `of` method. Should `LMParams` be renamed to `LMSParams`? src/java.base/share/classes/sun/security/provider/HSS.java line 294: > 292: LMOTSignature(byte[] sigArray, LMOTSParams lmotsParams) throws > InvalidParameterException { > 293: int inLen = sigArray.length; > 294: if (inLen < 4) Add braces around the one-line block. Same as in lines 300, 173, 461, 472, 487, 569, 571, and 783. src/java.base/share/classes/sun/security/provider/HSS.java line 295: > 293: int inLen = sigArray.length; > 294: if (inLen < 4) > 295: throw new InvalidParameterException("Invalid LMS > signature"); This is LM-OTS signature. Also, give some explanation. Same on line 301. src/java.base/share/classes/sun/security/provider/HSS.java line 357: > 355: break; > 356: > 357: /* Remove commented-out lines if they cannot be supported on time. src/java.base/share/classes/sun/security/provider/HSS.java line 459: > 457: final byte[] sigArr; > 458: > 459: public LMSignature(byte[] sigArray, int offset, boolean > checkExactLen) throws InvalidParameterException { How about we throw a `SignatureException` here. `new HSSSignature` and `new LMOTSignature` all throw it. src/java.base/share/classes/sun/security/provider/HSS.java line 528: > 526: // update()-digest() sequence) which is parametrized so that the > digest output is copied back into this buffer. > 527: // This way, we avoid memory allocations and some computations > that would have to be done otherwise. > 528: final byte[] hashBuf; I'm a little worried about the mutability of `hashBuf` and whether it's suitable to be put inside `LMOTSParams`. By using `of` to return an `LMOTSParams` object we have the chance to return cached objects in the future. There should always be one `hashBuf` for each LM-OTS verification, and this is not clear from the current code. src/java.base/share/classes/sun/security/provider/HSS.java line 659: > 657: } > 658: public byte[] lmotsPubKeyCandidate(LMSignature lmSig, byte[] > message, LMSPublicKey pKey) > 659: throws NoSuchAlgorithmException, DigestException { `DigestException` should not happen because we allocate all the buffer ourselves. `NoSuchAlgorithmException` should not happen because we should have all the algorithms. If they do happen, that's not user problem at all. I think the usual way is to wrap them into a `ProviderException`. This is also true in `lmsVerify()`. src/java.base/share/classes/sun/security/provider/HSS.java line 662: > 660: LMOTSignature lmOtSig = lmSig.lmotSig; > 661: if (lmOtSig.otSigType != pKey.otsType) { > 662: throw new IllegalArgumentException("OTS public key type > and OTS signature type do not match"); I'd rather throw `SignatureException`. This method is actually verifying an LM-OTS signature, right? src/java.base/share/classes/sun/security/provider/HSS.java line 736: > 734: } > 735: } > 736: throw new InvalidKeySpecException(); Give an error message. Try look at what other factories are doing. Same for lines 751, 768, 727, 44, 49, and 57. src/java.base/share/classes/sun/security/provider/HSS.java line 745: > 743: > 744: @Override > 745: protected <T extends KeySpec> T engineGetKeySpec(Key key, > Class<T> keySpec) throws InvalidKeySpecException { Usually when `key` is null an `InvalidKeySpecException` is thrown. Here it's an NPE. src/java.base/share/classes/sun/security/provider/HSS.java line 809: > 807: HSSSignature(byte[] sigArr, int pubKeyL, String pubKeyHashAlg) > throws SignatureException { > 808: if (sigArr.length < 4) { > 809: throw new SignatureException("Bad HSS signature"); Maybe you can say why it is bad. This also applies to "Invalid HSS public key", "Invalid LMS signature" and "Invalid LMS public key" messages. src/java.base/share/classes/sun/security/provider/HSS.java line 823: > 821: index += siglist[i].sigArrayLength(); > 822: pubList[i] = new LMSPublicKey(sigArr, index, false); > 823: if > (!pubList[i].getDigestAlgorithm().equals(pubKeyHashAlg)) { Comparing hash algorithm is not enough. Length (`m`) should also be compared. src/java.base/share/classes/sun/security/provider/HSS.java line 829: > 827: } > 828: siglist[Nspk] = new LMSignature(sigArr, index, true); > 829: } catch (Exception E) { The `SignatureException` thrown on line 824 does not need to be wrapped into another `SignatureException`. Maybe just catch `InvalidKeyException` (if you throw `SignatureException` in `new LMSSignature`). ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185459409 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185523625 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185518085 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185540342 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185521512 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185512129 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185533184 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185503139 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185544334 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185546621 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185508073 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185535770 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185536879 PR Review Comment: https://git.openjdk.org/jdk/pull/13691#discussion_r1185497769