* * Copyright 2018 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http:www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *

package conn

import (
	
	
	
	
	
	
	
	
)
rekeyAEAD holds the necessary information for an AEAD based on AES-GCM that performs nonce-based key derivation and XORs the nonce with a random mask.
KeySizeError signals that the given key does not have the correct size.
type KeySizeError int

func ( KeySizeError) () string {
	return "alts/conn: invalid key size " + strconv.Itoa(int())
}
newRekeyAEAD creates a new instance of aes128gcm with rekeying. The key argument should be 44 bytes, the first 32 bytes are used as a key for HKDF-expand and the remainining 12 bytes are used as a random mask for the counter.
func ( []byte) (*rekeyAEAD, error) {
	 := len()
	if  != kdfKeyLen+nonceLen {
		return nil, KeySizeError()
	}
	return &rekeyAEAD{
		kdfKey:     [:kdfKeyLen],
		kdfCounter: make([]byte, kdfCounterLen),
		nonceMask:  [kdfKeyLen:],
		nonceBuf:   make([]byte, nonceLen),
		gcmAEAD:    nil,
	}, nil
}
Seal rekeys if nonce[2:8] is different than in the last call, masks the nonce, and calls Seal for aes128gcm.
func ( *rekeyAEAD) (, , ,  []byte) []byte {
	if  := .rekeyIfRequired();  != nil {
		panic(fmt.Sprintf("Rekeying failed with: %s", .Error()))
	}
	maskNonce(.nonceBuf, , .nonceMask)
	return .gcmAEAD.Seal(, .nonceBuf, , )
}
Open rekeys if nonce[2:8] is different than in the last call, masks the nonce, and calls Open for aes128gcm.
func ( *rekeyAEAD) (, , ,  []byte) ([]byte, error) {
	if  := .rekeyIfRequired();  != nil {
		return nil, 
	}
	maskNonce(.nonceBuf, , .nonceMask)
	return .gcmAEAD.Open(, .nonceBuf, , )
}
rekeyIfRequired creates a new aes128gcm AEAD if the existing AEAD is nil or cannot be used with given nonce.
func ( *rekeyAEAD) ( []byte) error {
	 := [kdfCounterOffset : kdfCounterOffset+kdfCounterLen]
	if .gcmAEAD != nil && bytes.Equal(, .kdfCounter) {
		return nil
	}
	copy(.kdfCounter, )
	,  := aes.NewCipher(hkdfExpand(.kdfKey, .kdfCounter))
	if  != nil {
		return 
	}
	.gcmAEAD,  = cipher.NewGCM()
	return 
}
maskNonce XORs the given nonce with the mask and stores the result in dst.
func (, ,  []byte) {
	 := binary.LittleEndian.Uint64([:sizeUint64])
	 := binary.LittleEndian.Uint32([sizeUint64:])
	 := binary.LittleEndian.Uint64([:sizeUint64])
	 := binary.LittleEndian.Uint32([sizeUint64:])
	binary.LittleEndian.PutUint64([:sizeUint64], ^)
	binary.LittleEndian.PutUint32([sizeUint64:], ^)
}
NonceSize returns the required nonce size.
func ( *rekeyAEAD) () int {
	return .gcmAEAD.NonceSize()
}
Overhead returns the ciphertext overhead.
func ( *rekeyAEAD) () int {
	return .gcmAEAD.Overhead()
}
hkdfExpand computes the first 16 bytes of the HKDF-expand function defined in RFC5869.
func (,  []byte) []byte {
	 := hmac.New(sha256.New, )
	.Write()
	.Write([]byte{0x01}[:])
	return .Sum(nil)[:aeadKeyLen]