Skip to content

Commit

Permalink
Use subtle.XORBytes and avoid unnecessary copies/allocations in `Co…
Browse files Browse the repository at this point in the history
…mputePRF`

PiperOrigin-RevId: 712886152
Change-Id: Id336a11c2d68e0e3861a3358e6b2d2f3fac0fd46
  • Loading branch information
morambro authored and copybara-github committed Jan 7, 2025
1 parent c271797 commit cbb8e6b
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions prf/subtle/aes_cmac.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func NewAESCMACPRF(key []byte) (*AESCMACPRF, error) {
var err error
aesCmac.bc, err = aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("Could not obtain cipher: %v", err)
return nil, fmt.Errorf("could not obtain cipher: %v", err)
}
bs := aesCmac.bc.BlockSize()
zeroBlock := make([]byte, bs)
Expand All @@ -60,13 +60,16 @@ func NewAESCMACPRF(key []byte) (*AESCMACPRF, error) {
// ValidateAESCMACPRFParams checks that the key is the recommended size for AES-CMAC.
func ValidateAESCMACPRFParams(keySize uint32) error {
if keySize != recommendedKeySize {
return fmt.Errorf("Recommended key size for AES-CMAC is %d, but %d given", recommendedKeySize, keySize)
return fmt.Errorf("recommended key size for AES-CMAC is %d, but %d given", recommendedKeySize, keySize)
}
return nil
}

// ComputePRF computes the AES-CMAC for the given key and data, returning outputLength bytes.
// The timing of this function will only depend on len(data), and not leak any additional information about the key or the data.
// ComputePRF computes the AES-CMAC for the given key and data, returning
// outputLength bytes.
//
// The timing of this function will only depend on len(data), and not leak any
// additional information about the key or the data.
func (a AESCMACPRF) ComputePRF(data []byte, outputLength uint32) ([]byte, error) {
// Setup
bs := a.bc.BlockSize()
Expand All @@ -77,40 +80,38 @@ func (a AESCMACPRF) ComputePRF(data []byte, outputLength uint32) ([]byte, error)
// Pad
flag := false
n := len(data)/bs + 1
// if only depends on len(data).
// The following "if" only depends on len(data).
if len(data) > 0 && len(data)%bs == 0 {
n--
flag = true
}
mLast := make([]byte, bs)
mLastStart := (n - 1) * bs
for i := 0; i < bs; i++ {
// if depends on mLastStart and len(data), which depend on len(data)
// The following "if" only depends on mLastStart and len(data), which
// depend on len(data).
if i+mLastStart < len(data) {
mLast[i] = data[i+mLastStart]
} else if i+mLastStart == len(data) {
mLast[i] = pad
}
// if only depends on flag, which depends on len(data)
if flag {
mLast[i] ^= a.subkey1[i]
} else {
mLast[i] ^= a.subkey2[i]
}
}
input := make([]byte, bs)
// The following "if" only depends on flag, which depends on len(data).
if flag {
subtle.XORBytes(mLast, mLast, a.subkey1)
} else {
subtle.XORBytes(mLast, mLast, a.subkey2)
}

output := make([]byte, bs)
for i := 0; i < n; i++ {
// if depends on n, which depends on len(data)
// The following "if" depends on n, which depends on len(data).
if i+1 == n {
copy(input, mLast)
subtle.XORBytes(output, mLast, output)
} else {
copy(input, data[i*bs:(i+1)*bs])
}
for j := 0; j < bs; j++ {
input[j] ^= output[j]
subtle.XORBytes(output, data[i*bs:(i+1)*bs], output)
}
a.bc.Encrypt(output, input)
a.bc.Encrypt(output, output)
}
return output[:outputLength], nil
}
Expand Down

0 comments on commit cbb8e6b

Please sign in to comment.