Closed Bug 1623374 Opened 5 months ago Closed 4 months ago

Need to support the new PKCS #11 Message interface for AES GCM and ChaCha Poly

Categories

(NSS :: Libraries, enhancement, P1)

3.52
enhancement

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: rrelyea, Assigned: rrelyea)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

PKCS #11 defines a new interface for handling AEAD type ciphers that allow multiple AEAD operations without repeating the key schedule. It also allows tokens to keep track of the number of operations, and generate IVs (depending on the cipher).

We need to:

  1. implement those new functions in softoken.
  2. make those interfaces call aes_gcm and chacha20_poly1503 (and make adjustments for those ciphers).
  3. create new pk11wrap interfaces that also squash the api differences between the various mechanisms for aead (similiar to the way we do it for CBC and ECB crypto today).
  4. write tests for the new interfaces
  5. modify ssl to use those new interfaces
Assignee: nobody → rrelyea

related to bug 1560063

Status: NEW → ASSIGNED

related bug 1529440

PKCS #11 defines a new interface for handling AEAD type ciphers that allow
multiple AEAD operations without repeating the key schedule. It also allows
tokens to keep track of the number of operations, and generate IVs (depending
on the cipher).

This patch:
1. implement those new functions in softoken.
With the addition of CKF_MESSAGE_* flags to various mechanism, we need
to strip them when using the version 2 API of softoken (since there are
no C_Message* function in version 2). For that we need a separate
C_GetMechanismInfo function. We use the same trick we used to have
a separate version function for the V2 interface.
Also now that the new message functions are in their own file, they
still need access to the common Session state processing functions.
those have gone from static to exported within softoken to accomidate
that. Same with sftk_MapDecryptError() (sftk_MapVerifyError() was also
made global, though nothing else is yet using it).
Only C_MessageEncrptInit(), C_EncryptMessage(), C_MessageEncryptFinal,
C_MessageDecryptInit(), C_DecryptMessage(), and C_MessageDecryptFinal
are implemented. C_EncryptMessageBegin(), C_EncryptMessageNext(),
C_DecryptMessageBegin(), and C_DecryptMessageNext() are all
part of the multi-part withing a multi-part operation and
are only necessary for things like S/MIME (potentially). If we wanted
to implement them, we would need more functions exported from freebl
(and initaead, updateaead, finalaead for each mechanism type).
2. make those interfaces call aes_gcm and chacha20_poly1503
(and make adjustments for those ciphers).
For AES, I added a new function AES_AEAD, which handles both encrypt
and decrypt. Internally, the gcm functions (both the generic gcm and
the intel gcm wrapper) had their init functions split into key scheduling
and counter mode/tag initialization. The latter is still called from
init, but the former is now for each update call. IV generation is
handled by a single function in gcm.c, and shared with intel_gcm_wrapper.c
Since the AES functions already know about the underlying PKCS #11
mechanism parameters, the new AEAD functions also parse the PKCS #11 GCM
parameters.
For Chacha/Poly new aead update functions were created called
ChaChaPoly1305_Encrypt and ChaChaChaPoly1305_Decrypt. There was no
Message specific initialization in the existing chacha_init, so no
changes were needed there. The primary difference between
_Encrypt/_Decrypt and _Seal/_Open is the fact that the tag is put at
the end of the encrypted data buffer in the latter, and in a generic
buffer in the former.
3. create new pk11wrap interfaces that also squash the api differences
between the various mechanisms for aead (similiar to the way we do it for
CBC and ECB crypto today).
To accomplish this I added PK11_AEADOp() and PK11_AEADRawOp(). Both
functions handle the case where the token only supports the single shot
interface, by using the single short interface to simulate the
Message interface. The PK11_AEADOp() also smooths out the
differences in the parameters and symantics of the various mechanism
so the application does not need to worry about the PKCS #11 differences
in the mechanism. Both use contexts from the standard
PK11_CreateContext(), so key schedules are done once for each key rather
than once for each message. MESSAGE/AEAD operations are selected by adding
the psuedo attribute flag CKA_NSS_MESSAGE to the requested operation
(CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, CKA_VERIFY).
4. write tests for the new interfaces
Tests were added to make sure the PK11_AEADRawOp interface works,
The single shot interface is used to test output of the message interface
we also use two test only functions to force the connection to use
the simulation interface, which is also compared to the non-simulate
inteface. The AES_GCM also tests various IV generators.

Blocks: 1529440, 1560063

Bob, do you plan to add some performance tests for the new interface as part of these patches? It would be good to see whether encrypting multiple messages is faster with the new mode.

I hadn't planned on it. Do we have some already that I can run?

bltest -E|-D -p might be what we're looking for here. Using the message mode in there should show gains.

Ok, I'll take a look adding message to bltest. I was hoping for some SSL based tests, though, since that will test the full integration.

bob

Of course the RH reason is we want AES-GCM to be FIPS validated, and for that we need to do IV generation in the token (which also requires the message interface).

Priority: -- → P1

Update ssl to use the new PK11_AEADOp() interface.

  1. We restore the use of PK11Context_Create() for AEAD operations.
  2. AES GCM and CHACHA/Poly specific functions are no longer needed as
    PK11_AEADOp() handles all the mechanism specific processing.
  3. TLS semantic differences between the two algorithms is handled by their
    parameters:
    1. Nonce length is the length of the nonce counter. If it's zero, then
      XOR_Counter is used (and the nonce length is the
      sizeof(sslSequenceNumber)).
    2. IV length is the full IV length - nonce length.
    3. TLS 1.3 always uses XOR_Counter.
  4. The IV is returned from the token in the encrypt case. Only in the explict
    nonce case is it examined. (The code depends on the fact that the count in
    the token will match sslSequenceNumber). I did have assert code to verify
    this was happening for testing, but it's removed from this patch it can be
    added back.
  5. All the decrypt instances of XOR_Counter IV creation have been colapsed
    into tls13_WriteNonce().
  6. Even tough PK11_AEADOp returns and accepts the tag separately (for encrypt
    and decrypt respectively). The SSL code still returns the values as
    buffer||tag.
  7. tls13_AEAD() has been enhanced so all uses of AEAD outside of the TLS
    stream can use it instead of their own wrapped version. It can handle streams
    (CreateContext() tls13_AEAD() tls13_AEAD() DestroyContext()) or single shot
    tls13_AEAD(context=NULL). In the later case, the keys for the single shot
    operation should not be resued.
  8. libssl_internals.c in the gtests directory has been updated to handle
    advancing the internal iv counter when we artifically advance the seqNum.
    Since we don't have access to any token iv counter (including softoken),
    The code switches to simulated message mode, and updates the simulated state
    as appropriate. (obviously this is for testing only code as it reaches into
    normally private data structures).

Hey Kevin,

I've added you as a reviewer for this. If you have the time to look at these changes, it might be a good way to familiarize yourself more with this code. Also, you are likely to catch stuff I won't. I haven't looked yet myself.

Flags: needinfo?(kjacobs.bugzilla)

I'll probably add kevin on the hkdf patches as well. They are smaller and easier than the gcm patches.

Done and thanks. Happy to look at any others that come along.

Flags: needinfo?(kjacobs.bugzilla)
Status: ASSIGNED → RESOLVED
Closed: 4 months ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.