1

I am implementing a provider for AES for the Cipher class of the JCA (Java Cryptography Architecture).

The class Cipher adopts the init(), update(), doFinal() paradigm. The init() method is called to initialize the cipher. The method update() is used to provide input data that must be encrypted or decrypted. The method doFinal() finalizes the encryption or decryption process by handling things such as padding.

My question is: according to the JCA specifications, does the update() method have to return partially encrypted or decrypted data? Is it valid not to return data when the method update() is called and process all the data when the the method doFinal() is called? I am asking because the implementation of my provider would be much more efficient if I can process all the data at once in the doFinal() method, instead of process them partially with the update() method.

lucas
  • 11
  • 1
  • 2
  • Not only do you not have to return any data from update, block ciphers in one of their block modes *cannot* output any data until they have received at least a full block's worth of input. So for example with AES in ECB mode, if you want to encrypt 16 bytes you can call update 16 times with each of the bytes. The first 15 times nothing will be return and on the 16th the encrypted block will be return. Then the final call to doFinal() will return nothing. – President James K. Polk Apr 14 '20 at 17:21
  • Thank you for your comment. Let me clarify this. Assume that there is a single call to the method update() with 30 bytes. This is possible according to the Cipher specs. Normally, I would return 16 bytes and keep the remaining 14 buffered internally. My question is : can I buffer the all 30 bytes and process them entirely with doFinal()? – lucas Apr 14 '20 at 22:58
  • Yes, that is absolutely consistent with API. That doesn't mean that poorly written programs won't barf. – President James K. Polk Apr 14 '20 at 23:10
  • Oh thanks for the answer. This is good to know. Did you find this information in some official reference online or does it come from your experience? Thanks! – lucas Apr 15 '20 at 00:22
  • Actually, they did just that with the GCM implementation. I'm not sure that they still do, but if it was in the OpenJDK, then you can be certain that it is OK. Of course the result of `engineGetOutputSize(int inputLen)` will get a bit ugly, as you can only return the max value. That brings me to the next point actually, you do understand that you need to implement `CipherSpi`, right? – Maarten Bodewes Apr 15 '20 at 00:23
  • Side note: you can use the back-tick character `\`` (under the `~` key on US keyboards, which is below the ESC key) to format inline code. – Maarten Bodewes Apr 15 '20 at 00:32
  • Yes. I am implementing the `CipherSpi` interface. Yes, if they did that it is probably legit. I think I saw that behavior with AES/GCM in Android. If I am not mistaken, buffering is also necessary for asymmetric encryption, right? Thank you for your answer and suggestions. – lucas Apr 15 '20 at 01:25
  • The official reference for APIs is simply the [Javadocs](https://docs.oracle.com/en/java/javase/11/docs/api/index.html). If there are non-api details that must be understood then they're published in a separate document. For example, implement a provider involves a whole raft of such details, which are documented [here](https://docs.oracle.com/en/java/javase/11/security/howtoimplaprovider.html#GUID-C485394F-08C9-4D35-A245-1B82CDDBC031). – President James K. Polk Apr 15 '20 at 12:08
  • Thank you. I was just looking for someting explicitly saying that it can be done. – lucas Apr 19 '20 at 20:55

0 Answers0