184 * If internal data, data is decrypted internally. |
184 * If internal data, data is decrypted internally. |
185 * |
185 * |
186 * If external data(app), return a new ByteBuffer with data to |
186 * If external data(app), return a new ByteBuffer with data to |
187 * process. |
187 * process. |
188 */ |
188 */ |
189 ByteBuffer decrypt(MAC signer, |
189 ByteBuffer decrypt(Authenticator authenticator, |
190 CipherBox box, ByteBuffer bb) throws BadPaddingException { |
190 CipherBox box, ByteBuffer bb) throws BadPaddingException { |
191 |
191 |
192 if (internalData) { |
192 if (internalData) { |
193 decrypt(signer, box); // MAC is checked during decryption |
193 decrypt(authenticator, box); // MAC is checked during decryption |
194 return tmpBB; |
194 return tmpBB; |
195 } |
195 } |
196 |
196 |
197 BadPaddingException reservedBPE = null; |
197 BadPaddingException reservedBPE = null; |
198 int tagLen = signer.MAClen(); |
198 int tagLen = |
|
199 (authenticator instanceof MAC) ? ((MAC)authenticator).MAClen() : 0; |
199 int cipheredLength = bb.remaining(); |
200 int cipheredLength = bb.remaining(); |
200 |
201 |
201 if (!box.isNullCipher()) { |
202 if (!box.isNullCipher()) { |
202 // sanity check length of the ciphertext |
|
203 if (!box.sanityCheck(tagLen, cipheredLength)) { |
|
204 throw new BadPaddingException( |
|
205 "ciphertext sanity check failed"); |
|
206 } |
|
207 |
|
208 try { |
203 try { |
|
204 // apply explicit nonce for AEAD/CBC cipher suites if needed |
|
205 int nonceSize = |
|
206 box.applyExplicitNonce(authenticator, contentType(), bb); |
|
207 |
|
208 // decrypt the content |
|
209 if (box.isAEADMode()) { |
|
210 // DON'T encrypt the nonce_explicit for AEAD mode |
|
211 bb.position(bb.position() + nonceSize); |
|
212 } // The explicit IV for CBC mode can be decrypted. |
|
213 |
209 // Note that the CipherBox.decrypt() does not change |
214 // Note that the CipherBox.decrypt() does not change |
210 // the capacity of the buffer. |
215 // the capacity of the buffer. |
211 box.decrypt(bb, tagLen); |
216 box.decrypt(bb, tagLen); |
|
217 bb.position(nonceSize); // We don't actually remove the nonce. |
212 } catch (BadPaddingException bpe) { |
218 } catch (BadPaddingException bpe) { |
213 // RFC 2246 states that decryption_failed should be used |
219 // RFC 2246 states that decryption_failed should be used |
214 // for this purpose. However, that allows certain attacks, |
220 // for this purpose. However, that allows certain attacks, |
215 // so we just send bad record MAC. We also need to make |
221 // so we just send bad record MAC. We also need to make |
216 // sure to always check the MAC to avoid a timing attack |
222 // sure to always check the MAC to avoid a timing attack |
217 // for the same issue. See paper by Vaudenay et al and the |
223 // for the same issue. See paper by Vaudenay et al and the |
218 // update in RFC 4346/5246. |
224 // update in RFC 4346/5246. |
219 // |
225 // |
220 // Failover to message authentication code checking. |
226 // Failover to message authentication code checking. |
221 reservedBPE = bpe; |
227 reservedBPE = bpe; |
222 } finally { |
228 } |
223 bb.rewind(); |
229 } |
224 } |
230 |
225 } |
231 // Requires message authentication code for null, stream and block |
226 |
232 // cipher suites. |
227 if (tagLen != 0) { |
233 if ((authenticator instanceof MAC) && (tagLen != 0)) { |
|
234 MAC signer = (MAC)authenticator; |
228 int macOffset = bb.limit() - tagLen; |
235 int macOffset = bb.limit() - tagLen; |
229 |
236 |
230 // Note that although it is not necessary, we run the same MAC |
237 // Note that although it is not necessary, we run the same MAC |
231 // computation and comparison on the payload for both stream |
238 // computation and comparison on the payload for both stream |
232 // cipher and CBC block cipher. |
239 // cipher and CBC block cipher. |
295 * Please DON'T change the content of the ByteBuffer parameter! |
302 * Please DON'T change the content of the ByteBuffer parameter! |
296 */ |
303 */ |
297 private static boolean checkMacTags(byte contentType, ByteBuffer bb, |
304 private static boolean checkMacTags(byte contentType, ByteBuffer bb, |
298 MAC signer, boolean isSimulated) { |
305 MAC signer, boolean isSimulated) { |
299 |
306 |
|
307 int position = bb.position(); |
300 int tagLen = signer.MAClen(); |
308 int tagLen = signer.MAClen(); |
301 int lim = bb.limit(); |
309 int lim = bb.limit(); |
302 int macData = lim - tagLen; |
310 int macData = lim - tagLen; |
303 |
311 |
304 bb.limit(macData); |
312 bb.limit(macData); |