<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div class="moz-cite-prefix">Hi David/John -</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">I would submit that you're trying too
hard to make your life simple! :-)</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Cipher.wrap/unwrap are the correct
methods.</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">For example: <br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Cipher kem = Cipher.getInstance
("ECIES/GCM-128-64/KDF-SP800-108-COUNTER-SHA256");</div>
<div class="moz-cite-prefix">kem.init (Cipher.WRAP_MODE, pubkey);</div>
<div class="moz-cite-prefix">byte[] opaqueEncapsulatedKey = kem.wrap
(someOtherKey);</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">The "opaqueEncapsulatedKey" would
contain the data needed by the unwrap function - specifically a)
the ecies ephemeral public key, b) the fact that the derived key
is a GCM key of length 128 and that the GCM tag is 64 bytes long,
c) the KDF, d) (optional) any mixins other than defaults required
by the KDF - which would be passed in a parameter blob during
init. Cipher would NOT return the underlying generated secret
used to wrap the key. Just the public part of the key pair used
to do the ECDH operation against the passed in public key. In
the RSA case, the wrapped encrypting secret would be an opaque
data blob and would be part of the data passed to the unwrap
function.<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">If you want a key generated for other
purposes, then the right thing is using a KDF and a Key agreement
function in tandem. Strangely the KDF appears in the javacard
API for 3.1, but not in the JCE/JDK API.</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">"What's the difference between a
bureaucrat and an engineer? A bureaucrat takes small solvable
pieces and combines them into one insoluble mass."</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">In this case, Java provides a number of
flexible primitives that can be combined as needed. In this case,
the underlying Cipher implementation would wrap key agreement and
kdf and cipher (GCM) instances. It should return
UnsupportedOperationException for all operations execept
wrap/unwrap and the appropriate init methods.</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Later, Mike<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">On 8/19/2022 6:38 PM, David Hook wrote:<br>
</div>
<blockquote type="cite"
cite="mid:d511fabf-74dd-ec49-b686-a90eca14861a@cryptoworkshop.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<div class="moz-cite-prefix">Hi Mike,</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">KEMs can be used for key wrapping -
we've actually implemented support for this too. But they are
not actually key wrapping ciphers.<br>
</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">Here's a simple example of using
Kyber for key wrapping in BC:</div>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">
<pre style="background-color:#ffffff;color:#080808;font-family:'JetBrains Mono',monospace;font-size:11.3pt;"><span style="color:#000000;">SecretKey key </span>= <span style="color:#0033b3;">new </span>SecretKeySpec(<span style="color:#000000;">keyBytes</span>, <span style="color:#067d17;">"AES"</span>);
<span style="color:#000000;">w1</span>.init(<span style="color:#000000;">Cipher</span>.<span style="color:#871094;font-style:italic;">WRAP_MODE</span>, kp.getPublic(), <span style="color:#0033b3;">new </span>KEMParameterSpec(<span style="color:#067d17;">"AES-KWP"</span>));
<span style="color:#0033b3;">byte</span>[] <span style="color:#000000;">data </span>= <span style="color:#000000;">w1</span>.wrap(<span style="color:#000000;">key</span>);
<span style="color:#000000;">Cipher w2 </span>= <span style="color:#000000;">Cipher</span>.<span style="font-style:italic;">getInstance</span>(algorithm, <span style="color:#067d17;">"BCPQC"</span>);
<span style="color:#000000;">w2</span>.init(<span style="color:#000000;">Cipher</span>.<span style="color:#871094;font-style:italic;">UNWRAP_MODE</span>, kp.getPrivate(), <span style="color:#0033b3;">new </span>KEMParameterSpec(<span style="color:#067d17;">"AES-KWP"</span>));
<span style="color:#000000;">Key k </span>= <span style="color:#000000;">w2</span>.unwrap(<span style="color:#000000;">data</span>, <span style="color:#067d17;">"AES"</span>, <span style="color:#000000;">Cipher</span>.<span style="color:#871094;font-style:italic;">SECRET_KEY</span>);
The behavior in this case is in line with what is given in RFC 5990 for the RSA KEM. How it works is by using the key generated
by the KEM to create an AES-KWP key, which is then used to wrap keyBytes. The shortcoming is it means you have to generate the
secret key separately.
This is the problem though - a KEM can actually be used to generate a secret key for other purposes. For example, where
someone is trying to implement a hybrid KAS scheme. But there is currently no mechanism in the Java APIs for being able to
take advantage of this directly, hence our use of the KeyGenerator class and other people's attempts to make use of the KeyAgreement
class. The Cipher.wrap() returns a byte[] - to be used with a KEM for secret generation it would also have to return the
generated secret (I would probably also argue that passing a public key to wrap in order to generate an encapsulation of a
generated encrypted secret was not the correct use of the API either, but the fact remains a byte[] is not really going to cut it).
If you have any further questions, please feel free to ask. For what it is worth, I have been developing providers for the JCE/JCA since
the late 90's and am actually one of the people responsible for the introduction of the existing wrap/unwrap API in the Cipher class.
Thanks,
David
</pre>
</div>
<div class="moz-cite-prefix">On 20/8/22 07:53, Mike StJohns wrote:<br>
</div>
<blockquote type="cite"
cite="mid:814F78E4-9932-427B-8B65-1AFE5F9D32E2@comcast.net">
<pre class="moz-quote-pre" wrap="">Hi This implemented as part of Javax.crypto.Cipher. See the Java doc for the wrap and unwrap methods.
Mike
Sent from my iPad
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">On Aug 19, 2022, at 12:56, John Gray <a class="moz-txt-link-rfc2396E" href="mailto:John.Gray@entrust.com" moz-do-not-send="true"><John.Gray@entrust.com></a> wrote:
We are starting to make use of the new PQ algorithms adopted by NIST for prototyping and development of standards. In particular we are working on a composite KEM standard:
See: <a class="moz-txt-link-freetext" href="https://datatracker.ietf.org/doc/draft-ounsworth-pq-composite-kem/" moz-do-not-send="true">https://datatracker.ietf.org/doc/draft-ounsworth-pq-composite-kem/</a>
However, there is no KEM interface in the JCA (which make sense because these are new algorithms, although RSA-KEM has been out since 2010).
I can add one into our toolkit (and I think David may have already added on into BC), but I assume at some point there will be an official one added in Java and likely it won't be identical to what we do even if it is very close, which would cause backwards compatibility pain... Perhaps we could collaborate on extending the JCA to support KEM? Essentially it requires methods.
ss, ct := encapsulate(PublicKey)
ss := decapsulate(PrivateKey, ct)
-ss is a shared secret (could come back as a Java SecretKey if you wanted as it would usually be used to derive something like an AES afterwards)
-ct is a Cipher Text (a byte array would make sense)
-Public and Private Keys would use the regular public and private key interface.
-An object holding the ss and ct from the encapsulate() method could be returned, with accessor methods to get the ss and ct. It could be called 'EncapsulatedKEMData' for example.
Likely you would want a new type of KEM crypto object (like you have for Signature, MessageDigest, Cipher, Mac, SecureRandom, KeyAgreement.. etc). Calling it KEM would seem to make sense. 😊 It could also use similar calling patterns and have a KEM.initKEM(keypair.getPublic()) or KEM.initKEM(keypair.getPrivate()), and then you would just call KEM.encapsulate() or KEM.decapsulate(ct).
Then algorithms could be registered in providers as usual:
put("KEM.Kyber","com.blah.Kyber")
put("KEM.compositeKEM","com.entrust.toolkit.crypto.kem.compositeKEM")
Then the above methods (encapsulate and decapsulate) could be defined in that new object type. Then we would be able to make use of it and not have to worry about incompatibility issues down the road...
Cheers,
John Gray
Any email and files/attachments transmitted with it are confidential and are intended solely for the use of the individual or entity to whom they are addressed. If this message has been sent to you in error, you must not copy, distribute or disclose of the information it contains. Please notify Entrust immediately and delete the message from your system.
</pre>
</blockquote>
</blockquote>
<p><br>
</p>
</blockquote>
<p><br>
</p>
</body>
</html>