Path: blob/master/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java
41159 views
/*1* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.provider;2627import java.lang.invoke.MethodHandles;28import java.lang.invoke.VarHandle;29import java.nio.ByteOrder;3031/**32* Optimized methods for converting between byte[] and int[]/long[], both for33* big endian and little endian byte orders.34*35* NOTE that ArrayIndexOutOfBoundsException will be thrown if the bounds checks36* failed.37*38* This class may also be helpful in improving the performance of the39* crypto code in the SunJCE provider. However, for now it is only accessible by40* the message digest implementation in the SUN provider.41*42* @since 1.643* @author Andreas Sterbenz44*/45final class ByteArrayAccess {4647private ByteArrayAccess() {48// empty49}5051static final class LE {52static final VarHandle INT_ARRAY53= MethodHandles.byteArrayViewVarHandle(int[].class,54ByteOrder.LITTLE_ENDIAN).withInvokeExactBehavior();5556static final VarHandle LONG_ARRAY57= MethodHandles.byteArrayViewVarHandle(long[].class,58ByteOrder.LITTLE_ENDIAN).withInvokeExactBehavior();59}6061static final class BE {62static final VarHandle INT_ARRAY63= MethodHandles.byteArrayViewVarHandle(int[].class,64ByteOrder.BIG_ENDIAN).withInvokeExactBehavior();6566static final VarHandle LONG_ARRAY67= MethodHandles.byteArrayViewVarHandle(long[].class,68ByteOrder.BIG_ENDIAN).withInvokeExactBehavior();69}7071/**72* int[] to byte[] conversion, little endian byte order.73*/74static void i2bLittle(int[] in, int inOfs, byte[] out, int outOfs, int len) {75len += outOfs;76while (outOfs < len) {77LE.INT_ARRAY.set(out, outOfs, in[inOfs++]);78outOfs += 4;79}80}8182// Store one 32-bit value into out[outOfs..outOfs+3] in little endian order.83static void i2bLittle4(int val, byte[] out, int outOfs) {84LE.INT_ARRAY.set(out, outOfs, val);85}8687/**88* byte[] to int[] conversion, big endian byte order.89*/90static void b2iBig(byte[] in, int inOfs, int[] out, int outOfs, int len) {91len += inOfs;92while (inOfs < len) {93out[outOfs++] = (int) BE.INT_ARRAY.get(in, inOfs);94inOfs += 4;95}96}9798// Special optimization of b2iBig(in, inOfs, out, 0, 64)99static void b2iBig64(byte[] in, int inOfs, int[] out) {100out[ 0] = (int) BE.INT_ARRAY.get(in, inOfs );101out[ 1] = (int) BE.INT_ARRAY.get(in, inOfs + 4);102out[ 2] = (int) BE.INT_ARRAY.get(in, inOfs + 8);103out[ 3] = (int) BE.INT_ARRAY.get(in, inOfs + 12);104out[ 4] = (int) BE.INT_ARRAY.get(in, inOfs + 16);105out[ 5] = (int) BE.INT_ARRAY.get(in, inOfs + 20);106out[ 6] = (int) BE.INT_ARRAY.get(in, inOfs + 24);107out[ 7] = (int) BE.INT_ARRAY.get(in, inOfs + 28);108out[ 8] = (int) BE.INT_ARRAY.get(in, inOfs + 32);109out[ 9] = (int) BE.INT_ARRAY.get(in, inOfs + 36);110out[10] = (int) BE.INT_ARRAY.get(in, inOfs + 40);111out[11] = (int) BE.INT_ARRAY.get(in, inOfs + 44);112out[12] = (int) BE.INT_ARRAY.get(in, inOfs + 48);113out[13] = (int) BE.INT_ARRAY.get(in, inOfs + 52);114out[14] = (int) BE.INT_ARRAY.get(in, inOfs + 56);115out[15] = (int) BE.INT_ARRAY.get(in, inOfs + 60);116}117118/**119* int[] to byte[] conversion, big endian byte order.120*/121static void i2bBig(int[] in, int inOfs, byte[] out, int outOfs, int len) {122len += outOfs;123while (outOfs < len) {124BE.INT_ARRAY.set(out, outOfs, in[inOfs++]);125outOfs += 4;126}127}128129// Store one 32-bit value into out[outOfs..outOfs+3] in big endian order.130static void i2bBig4(int val, byte[] out, int outOfs) {131BE.INT_ARRAY.set(out, outOfs, val);132}133134/**135* byte[] to long[] conversion, big endian byte order.136*/137static void b2lBig(byte[] in, int inOfs, long[] out, int outOfs, int len) {138len += inOfs;139while (inOfs < len) {140out[outOfs++] = (long) BE.LONG_ARRAY.get(in, inOfs);141inOfs += 8;142}143}144145// Special optimization of b2lBig(in, inOfs, out, 0, 128)146static void b2lBig128(byte[] in, int inOfs, long[] out) {147out[ 0] = (long) BE.LONG_ARRAY.get(in, inOfs );148out[ 1] = (long) BE.LONG_ARRAY.get(in, inOfs + 8);149out[ 2] = (long) BE.LONG_ARRAY.get(in, inOfs + 16);150out[ 3] = (long) BE.LONG_ARRAY.get(in, inOfs + 24);151out[ 4] = (long) BE.LONG_ARRAY.get(in, inOfs + 32);152out[ 5] = (long) BE.LONG_ARRAY.get(in, inOfs + 40);153out[ 6] = (long) BE.LONG_ARRAY.get(in, inOfs + 48);154out[ 7] = (long) BE.LONG_ARRAY.get(in, inOfs + 56);155out[ 8] = (long) BE.LONG_ARRAY.get(in, inOfs + 64);156out[ 9] = (long) BE.LONG_ARRAY.get(in, inOfs + 72);157out[10] = (long) BE.LONG_ARRAY.get(in, inOfs + 80);158out[11] = (long) BE.LONG_ARRAY.get(in, inOfs + 88);159out[12] = (long) BE.LONG_ARRAY.get(in, inOfs + 96);160out[13] = (long) BE.LONG_ARRAY.get(in, inOfs + 104);161out[14] = (long) BE.LONG_ARRAY.get(in, inOfs + 112);162out[15] = (long) BE.LONG_ARRAY.get(in, inOfs + 120);163}164165/**166* long[] to byte[] conversion, big endian byte order.167*/168static void l2bBig(long[] in, int inOfs, byte[] out, int outOfs, int len) {169len += outOfs;170while (outOfs < len) {171BE.LONG_ARRAY.set(out, outOfs, in[inOfs++]);172outOfs += 8;173}174}175176/**177* byte[] to long[] conversion, little endian byte order178*/179static void b2lLittle(byte[] in, int inOfs, long[] out, int outOfs, int len) {180len += inOfs;181while (inOfs < len) {182out[outOfs++] = (long) LE.LONG_ARRAY.get(in, inOfs);183inOfs += 8;184}185}186187188/**189* long[] to byte[] conversion, little endian byte order190*/191static void l2bLittle(long[] in, int inOfs, byte[] out, int outOfs, int len) {192len += outOfs;193while (outOfs < len) {194LE.LONG_ARRAY.set(out, outOfs, in[inOfs++]);195outOfs += 8;196}197}198}199200201