Mercurial > hg > openjdk > jdk9 > jdk
changeset 16971:0c8f43317c1f
8177784: Use CounterMode intrinsic for AES/GCM
Reviewed-by: mullan, psandoz, chegar
author | ascarpino |
---|---|
date | Wed, 12 Apr 2017 12:57:49 -0700 |
parents | 23255bc8606d |
children | ede22275fbfa |
files | src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java src/java.base/share/classes/com/sun/crypto/provider/GCTR.java |
diffstat | 2 files changed, 25 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java Tue Apr 11 14:18:22 2017 -0400 +++ b/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java Wed Apr 12 12:57:49 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,10 +42,10 @@ * @author Andreas Sterbenz * @since 1.4.2 */ -final class CounterMode extends FeedbackCipher { +class CounterMode extends FeedbackCipher { // current counter value - private final byte[] counter; + final byte[] counter; // encrypted bytes of the previous counter value private final byte[] encryptedCounter;
--- a/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java Tue Apr 11 14:18:22 2017 -0400 +++ b/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java Wed Apr 12 12:57:49 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,52 +29,43 @@ package com.sun.crypto.provider; -import java.security.*; -import javax.crypto.*; +import javax.crypto.IllegalBlockSizeException; import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE; /** * This class represents the GCTR function defined in NIST 800-38D - * under section 6.5. It needs to be constructed w/ an initialized - * cipher object, and initial counter block(ICB). Given an input X - * of arbitrary length, it processes and returns an output which has - * the same length as X. The invariants of this class are: - * - * (1) The length of intialCounterBlk (and also of its clones, e.g., - * fields counter and counterSave) is equal to AES_BLOCK_SIZE. - * - * (2) After construction, the field counter never becomes null, it - * always contains a byte array of length AES_BLOCK_SIZE. + * under section 6.5. With a given cipher object and initial counter + * block, a counter mode operation is performed. Blocksize is limited + * to 16 bytes. * * If any invariant is broken, failures can occur because the * AESCrypt.encryptBlock method can be intrinsified on the HotSpot VM * (see JDK-8067648 for details). * + * The counter mode operations can be intrinsified and parallelized + * by using CounterMode.implCrypt() if HotSpot VM supports it on the + * architecture. + * * <p>This function is used in the implementation of GCM mode. * * @since 1.8 */ -final class GCTR { - - // these fields should not change after the object has been constructed - private final SymmetricCipher aes; - private final byte[] icb; +final class GCTR extends CounterMode { - // the current counter value - private byte[] counter; - - // needed for save/restore calls - private byte[] counterSave = null; - - // NOTE: cipher should already be initialized GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) { - this.aes = cipher; + super(cipher); if (initialCounterBlk.length != AES_BLOCK_SIZE) { throw new RuntimeException("length of initial counter block (" + initialCounterBlk.length + ") not equal to AES_BLOCK_SIZE (" + AES_BLOCK_SIZE + ")"); } - this.icb = initialCounterBlk; - this.counter = icb.clone(); + + iv = initialCounterBlk; + reset(); + } + + @Override + String getFeedback() { + return "GCTR"; } // input must be multiples of 128-bit blocks when calling update @@ -89,23 +80,11 @@ throw new RuntimeException("output buffer too small"); } - byte[] encryptedCntr = new byte[AES_BLOCK_SIZE]; - - int numOfCompleteBlocks = inLen / AES_BLOCK_SIZE; - for (int i = 0; i < numOfCompleteBlocks; i++) { - aes.encryptBlock(counter, 0, encryptedCntr, 0); - for (int n = 0; n < AES_BLOCK_SIZE; n++) { - int index = (i * AES_BLOCK_SIZE + n); - out[outOfs + index] = - (byte) ((in[inOfs + index] ^ encryptedCntr[n])); - } - GaloisCounterMode.increment32(counter); - } - return inLen; + return encrypt(in, inOfs, inLen, out, outOfs); } // input can be arbitrary size when calling doFinal - protected int doFinal(byte[] in, int inOfs, int inLen, byte[] out, + int doFinal(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) throws IllegalBlockSizeException { try { if (inLen < 0) { @@ -118,7 +97,7 @@ if (lastBlockSize != 0) { // do the last partial block byte[] encryptedCntr = new byte[AES_BLOCK_SIZE]; - aes.encryptBlock(counter, 0, encryptedCntr, 0); + embeddedCipher.encryptBlock(counter, 0, encryptedCntr, 0); for (int n = 0; n < lastBlockSize; n++) { out[outOfs + completeBlkLen + n] = (byte) ((in[inOfs + completeBlkLen + n] ^ @@ -131,28 +110,4 @@ } return inLen; } - - /** - * Resets the content of this object to when it's first constructed. - */ - void reset() { - System.arraycopy(icb, 0, counter, 0, icb.length); - counterSave = null; - } - - /** - * Save the current content of this object. - */ - void save() { - this.counterSave = this.counter.clone(); - } - - /** - * Restores the content of this object to the previous saved one. - */ - void restore() { - if (this.counterSave != null) { - this.counter = this.counterSave; - } - } }