@@ -1061,37 +1061,6 @@ void init(boolean decrypting, String algorithm, byte[] key)
1061
1061
this .K = sessionK [(decrypting ? 1 :0 )];
1062
1062
}
1063
1063
1064
- /**
1065
- * Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].
1066
- * For decryption round keys, need to rotate right by 4 ints.
1067
- * @param kr The round keys for encryption or decryption.
1068
- * @param decrypting True if 'kr' is for decryption and false otherwise.
1069
- */
1070
- private static final int [] expandToSubKey (int [][] kr , boolean decrypting ) {
1071
- int total = kr .length ;
1072
- int [] expK = new int [total *4 ];
1073
- if (decrypting ) {
1074
- // decrypting, rotate right by 4 ints
1075
- // i.e. i==0
1076
- for (int j =0 ; j <4 ; j ++) {
1077
- expK [j ] = kr [total -1 ][j ];
1078
- }
1079
- for (int i =1 ; i <total ; i ++) {
1080
- for (int j =0 ; j <4 ; j ++) {
1081
- expK [i *4 + j ] = kr [i -1 ][j ];
1082
- }
1083
- }
1084
- } else {
1085
- // encrypting, straight expansion
1086
- for (int i =0 ; i <total ; i ++) {
1087
- for (int j =0 ; j <4 ; j ++) {
1088
- expK [i *4 + j ] = kr [i ][j ];
1089
- }
1090
- }
1091
- }
1092
- return expK ;
1093
- }
1094
-
1095
1064
// check if the specified length (in bytes) is a valid keysize for AES
1096
1065
static boolean isKeySizeValid (int len ) {
1097
1066
for (int aesKeysize : AES_KEYSIZES ) {
@@ -1361,12 +1330,13 @@ private void makeSessionKey(byte[] k) throws InvalidKeyException {
1361
1330
k .length + " bytes" );
1362
1331
}
1363
1332
1333
+ final int BC = 4 ;
1334
+
1364
1335
int ROUNDS = getRounds (k .length );
1365
- int ROUND_KEY_COUNT = (ROUNDS + 1 ) * 4 ;
1336
+ int ROUND_KEY_COUNT = (ROUNDS + 1 ) * BC ;
1366
1337
1367
- int BC = 4 ;
1368
- int [][] Ke = new int [ROUNDS + 1 ][4 ]; // encryption round keys
1369
- int [][] Kd = new int [ROUNDS + 1 ][4 ]; // decryption round keys
1338
+ int [] Ke = new int [ROUND_KEY_COUNT ]; // encryption round keys
1339
+ int [] Kd = new int [ROUND_KEY_COUNT ]; // decryption round keys
1370
1340
1371
1341
int KC = k .length /4 ; // keylen in 32-bit elements
1372
1342
@@ -1384,8 +1354,8 @@ private void makeSessionKey(byte[] k) throws InvalidKeyException {
1384
1354
// copy values into round key arrays
1385
1355
int t = 0 ;
1386
1356
for (j = 0 ; (j < KC ) && (t < ROUND_KEY_COUNT ); j ++, t ++) {
1387
- Ke [t / 4 ][ t % 4 ] = tk [j ];
1388
- Kd [ROUNDS - (t / 4 )][ t % 4 ] = tk [j ];
1357
+ Ke [t ] = tk [j ];
1358
+ Kd [( ROUNDS - (t / BC ))* BC + ( t % BC ) ] = tk [j ];
1389
1359
}
1390
1360
int tt , rconpointer = 0 ;
1391
1361
while (t < ROUND_KEY_COUNT ) {
@@ -1409,32 +1379,35 @@ private void makeSessionKey(byte[] k) throws InvalidKeyException {
1409
1379
}
1410
1380
// copy values into round key arrays
1411
1381
for (j = 0 ; (j < KC ) && (t < ROUND_KEY_COUNT ); j ++, t ++) {
1412
- Ke [t / 4 ][ t % 4 ] = tk [j ];
1413
- Kd [ROUNDS - (t / 4 )][ t % 4 ] = tk [j ];
1382
+ Ke [t ] = tk [j ];
1383
+ Kd [( ROUNDS - (t / BC ))* BC + ( t % BC ) ] = tk [j ];
1414
1384
}
1415
1385
}
1416
1386
for (int r = 1 ; r < ROUNDS ; r ++) {
1417
1387
// inverse MixColumn where needed
1418
1388
for (j = 0 ; j < BC ; j ++) {
1419
- tt = Kd [r ][j ];
1420
- Kd [r ][j ] = U1 [(tt >>> 24 ) & 0xFF ] ^
1421
- U2 [(tt >>> 16 ) & 0xFF ] ^
1422
- U3 [(tt >>> 8 ) & 0xFF ] ^
1423
- U4 [ tt & 0xFF ];
1389
+ int idx = r *BC + j ;
1390
+ tt = Kd [idx ];
1391
+ Kd [idx ] = U1 [(tt >>> 24 ) & 0xFF ] ^
1392
+ U2 [(tt >>> 16 ) & 0xFF ] ^
1393
+ U3 [(tt >>> 8 ) & 0xFF ] ^
1394
+ U4 [ tt & 0xFF ];
1424
1395
}
1425
1396
}
1426
1397
1427
- // assemble the encryption (Ke) and decryption (Kd) round keys
1428
- // and expand them into arrays of ints.
1429
- int [] expandedKe = expandToSubKey (Ke , false ); // decrypting==false
1430
- int [] expandedKd = expandToSubKey (Kd , true ); // decrypting==true
1398
+ // For decryption round keys, need to rotate right by 4 ints.
1399
+ // Do that without allocating and zeroing the small buffer.
1400
+ int KdTail_0 = Kd [Kd .length - 4 ];
1401
+ int KdTail_1 = Kd [Kd .length - 3 ];
1402
+ int KdTail_2 = Kd [Kd .length - 2 ];
1403
+ int KdTail_3 = Kd [Kd .length - 1 ];
1404
+ System .arraycopy (Kd , 0 , Kd , 4 , Kd .length - 4 );
1405
+ Kd [0 ] = KdTail_0 ;
1406
+ Kd [1 ] = KdTail_1 ;
1407
+ Kd [2 ] = KdTail_2 ;
1408
+ Kd [3 ] = KdTail_3 ;
1409
+
1431
1410
Arrays .fill (tk , 0 );
1432
- for (int [] ia : Ke ) {
1433
- Arrays .fill (ia , 0 );
1434
- }
1435
- for (int [] ia : Kd ) {
1436
- Arrays .fill (ia , 0 );
1437
- }
1438
1411
ROUNDS_12 = (ROUNDS >=12 );
1439
1412
ROUNDS_14 = (ROUNDS ==14 );
1440
1413
limit = ROUNDS *4 ;
@@ -1444,8 +1417,11 @@ private void makeSessionKey(byte[] k) throws InvalidKeyException {
1444
1417
// erase the previous values in sessionK
1445
1418
Arrays .fill (sessionK [0 ], 0 );
1446
1419
Arrays .fill (sessionK [1 ], 0 );
1420
+ } else {
1421
+ sessionK = new int [2 ][];
1447
1422
}
1448
- sessionK = new int [][] { expandedKe , expandedKd };
1423
+ sessionK [0 ] = Ke ;
1424
+ sessionK [1 ] = Kd ;
1449
1425
}
1450
1426
1451
1427
/**
0 commit comments