Skip to content
This repository has been archived by the owner on Aug 27, 2022. It is now read-only.

Commit

Permalink
8261522: [PPC64] AES intrinsics write beyond the destination array
Browse files Browse the repository at this point in the history
Reviewed-by: lucy
  • Loading branch information
TheRealMDoerr committed Feb 17, 2021
1 parent 03b586b commit 05d5955
Showing 1 changed file with 56 additions and 44 deletions.
100 changes: 56 additions & 44 deletions src/hotspot/cpu/ppc/stubGenerator_ppc.cpp
Expand Up @@ -2598,7 +2598,7 @@ class StubGenerator: public StubCodeGenerator {

address start = __ function_entry();

Label L_doLast;
Label L_doLast, L_error;

Register from = R3_ARG1; // source array address
Register to = R4_ARG2; // destination array address
Expand Down Expand Up @@ -2628,7 +2628,7 @@ class StubGenerator: public StubCodeGenerator {

__ li (fifteen, 15);

// load unaligned from[0-15] to vsRet
// load unaligned from[0-15] to vRet
__ lvx (vRet, from);
__ lvx (vTmp1, fifteen, from);
__ lvsl (fromPerm, from);
Expand Down Expand Up @@ -2743,6 +2743,11 @@ class StubGenerator: public StubCodeGenerator {
__ cmpwi (CCR0, keylen, 52);
__ beq (CCR0, L_doLast);

#ifdef ASSERT
__ cmpwi (CCR0, keylen, 60);
__ bne (CCR0, L_error);
#endif

// 12th - 13th rounds
__ vcipher (vRet, vRet, vKey1);
__ vcipher (vRet, vRet, vKey2);
Expand All @@ -2763,29 +2768,30 @@ class StubGenerator: public StubCodeGenerator {
__ vcipher (vRet, vRet, vKey1);
__ vcipherlast (vRet, vRet, vKey2);

// store result (unaligned)
#ifdef VM_LITTLE_ENDIAN
__ lvsl (toPerm, to);
#else
__ lvsr (toPerm, to);
#endif
__ vspltisb (vTmp3, -1);
__ vspltisb (vTmp4, 0);
__ lvx (vTmp1, to);
__ lvx (vTmp2, fifteen, to);
#ifdef VM_LITTLE_ENDIAN
__ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask
__ vxor (toPerm, toPerm, fSplt); // swap bytes
#else
__ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask
// toPerm = 0x0F0E0D0C0B0A09080706050403020100
__ lvsl (toPerm, keypos); // keypos is a multiple of 16
__ vxor (toPerm, toPerm, fSplt);

// Swap Bytes
__ vperm (vRet, vRet, vRet, toPerm);
#endif
__ vperm (vTmp4, vRet, vRet, toPerm); // rotate data
__ vsel (vTmp2, vTmp4, vTmp2, vTmp3);
__ vsel (vTmp1, vTmp1, vTmp4, vTmp3);
__ stvx (vTmp2, fifteen, to); // store this one first (may alias)
__ stvx (vTmp1, to);

// store result (unaligned)
// Note: We can't use a read-modify-write sequence which touches additional Bytes.
Register lo = temp, hi = fifteen; // Reuse
__ vsldoi (vTmp1, vRet, vRet, 8);
__ mfvrd (hi, vRet);
__ mfvrd (lo, vTmp1);
__ std (hi, 0 LITTLE_ENDIAN_ONLY(+ 8), to);
__ std (lo, 0 BIG_ENDIAN_ONLY(+ 8), to);

__ blr();

#ifdef ASSERT
__ bind(L_error);
__ stop("aescrypt_encryptBlock: invalid key length");
#endif
return start;
}

Expand All @@ -2799,9 +2805,7 @@ class StubGenerator: public StubCodeGenerator {

address start = __ function_entry();

Label L_doLast;
Label L_do44;
Label L_do52;
Label L_doLast, L_do44, L_do52, L_error;

Register from = R3_ARG1; // source array address
Register to = R4_ARG2; // destination array address
Expand Down Expand Up @@ -2832,7 +2836,7 @@ class StubGenerator: public StubCodeGenerator {

__ li (fifteen, 15);

// load unaligned from[0-15] to vsRet
// load unaligned from[0-15] to vRet
__ lvx (vRet, from);
__ lvx (vTmp1, fifteen, from);
__ lvsl (fromPerm, from);
Expand Down Expand Up @@ -2861,6 +2865,11 @@ class StubGenerator: public StubCodeGenerator {
__ cmpwi (CCR0, keylen, 52);
__ beq (CCR0, L_do52);

#ifdef ASSERT
__ cmpwi (CCR0, keylen, 60);
__ bne (CCR0, L_error);
#endif

// load the 15th round key to vKey1
__ li (keypos, 240);
__ lvx (vKey1, keypos, key);
Expand Down Expand Up @@ -2897,6 +2906,7 @@ class StubGenerator: public StubCodeGenerator {

__ b (L_doLast);

__ align(32);
__ bind (L_do52);

// load the 13th round key to vKey1
Expand All @@ -2923,6 +2933,7 @@ class StubGenerator: public StubCodeGenerator {

__ b (L_doLast);

__ align(32);
__ bind (L_do44);

// load the 11th round key to vKey1
Expand Down Expand Up @@ -3000,29 +3011,30 @@ class StubGenerator: public StubCodeGenerator {
__ vncipher (vRet, vRet, vKey4);
__ vncipherlast (vRet, vRet, vKey5);

// store result (unaligned)
#ifdef VM_LITTLE_ENDIAN
__ lvsl (toPerm, to);
#else
__ lvsr (toPerm, to);
#endif
__ vspltisb (vTmp3, -1);
__ vspltisb (vTmp4, 0);
__ lvx (vTmp1, to);
__ lvx (vTmp2, fifteen, to);
#ifdef VM_LITTLE_ENDIAN
__ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask
__ vxor (toPerm, toPerm, fSplt); // swap bytes
#else
__ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask
// toPerm = 0x0F0E0D0C0B0A09080706050403020100
__ lvsl (toPerm, keypos); // keypos is a multiple of 16
__ vxor (toPerm, toPerm, fSplt);

// Swap Bytes
__ vperm (vRet, vRet, vRet, toPerm);
#endif
__ vperm (vTmp4, vRet, vRet, toPerm); // rotate data
__ vsel (vTmp2, vTmp4, vTmp2, vTmp3);
__ vsel (vTmp1, vTmp1, vTmp4, vTmp3);
__ stvx (vTmp2, fifteen, to); // store this one first (may alias)
__ stvx (vTmp1, to);

// store result (unaligned)
// Note: We can't use a read-modify-write sequence which touches additional Bytes.
Register lo = temp, hi = fifteen; // Reuse
__ vsldoi (vTmp1, vRet, vRet, 8);
__ mfvrd (hi, vRet);
__ mfvrd (lo, vTmp1);
__ std (hi, 0 LITTLE_ENDIAN_ONLY(+ 8), to);
__ std (lo, 0 BIG_ENDIAN_ONLY(+ 8), to);

__ blr();

#ifdef ASSERT
__ bind(L_error);
__ stop("aescrypt_decryptBlock: invalid key length");
#endif
return start;
}

Expand Down

0 comments on commit 05d5955

Please sign in to comment.