mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-11-01 00:59:34 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package ciphersuite provides the crypto operations needed for a DTLS CipherSuite
 | |
| package ciphersuite
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"errors"
 | |
| 
 | |
| 	"github.com/pion/dtls/v2/pkg/protocol"
 | |
| 	"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	errNotEnoughRoomForNonce = &protocol.InternalError{Err: errors.New("buffer not long enough to contain nonce")} //nolint:goerr113
 | |
| 	errDecryptPacket         = &protocol.TemporaryError{Err: errors.New("failed to decrypt packet")}               //nolint:goerr113
 | |
| 	errInvalidMAC            = &protocol.TemporaryError{Err: errors.New("invalid mac")}                            //nolint:goerr113
 | |
| )
 | |
| 
 | |
| func generateAEADAdditionalData(h *recordlayer.Header, payloadLen int) []byte {
 | |
| 	var additionalData [13]byte
 | |
| 	// SequenceNumber MUST be set first
 | |
| 	// we only want uint48, clobbering an extra 2 (using uint64, Golang doesn't have uint48)
 | |
| 	binary.BigEndian.PutUint64(additionalData[:], h.SequenceNumber)
 | |
| 	binary.BigEndian.PutUint16(additionalData[:], h.Epoch)
 | |
| 	additionalData[8] = byte(h.ContentType)
 | |
| 	additionalData[9] = h.Version.Major
 | |
| 	additionalData[10] = h.Version.Minor
 | |
| 	binary.BigEndian.PutUint16(additionalData[len(additionalData)-2:], uint16(payloadLen))
 | |
| 
 | |
| 	return additionalData[:]
 | |
| }
 | |
| 
 | |
| // examinePadding returns, in constant time, the length of the padding to remove
 | |
| // from the end of payload. It also returns a byte which is equal to 255 if the
 | |
| // padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
 | |
| //
 | |
| // https://github.com/golang/go/blob/039c2081d1178f90a8fa2f4e6958693129f8de33/src/crypto/tls/conn.go#L245
 | |
| func examinePadding(payload []byte) (toRemove int, good byte) {
 | |
| 	if len(payload) < 1 {
 | |
| 		return 0, 0
 | |
| 	}
 | |
| 
 | |
| 	paddingLen := payload[len(payload)-1]
 | |
| 	t := uint(len(payload)-1) - uint(paddingLen)
 | |
| 	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
 | |
| 	good = byte(int32(^t) >> 31)
 | |
| 
 | |
| 	// The maximum possible padding length plus the actual length field
 | |
| 	toCheck := 256
 | |
| 	// The length of the padded data is public, so we can use an if here
 | |
| 	if toCheck > len(payload) {
 | |
| 		toCheck = len(payload)
 | |
| 	}
 | |
| 
 | |
| 	for i := 0; i < toCheck; i++ {
 | |
| 		t := uint(paddingLen) - uint(i)
 | |
| 		// if i <= paddingLen then the MSB of t is zero
 | |
| 		mask := byte(int32(^t) >> 31)
 | |
| 		b := payload[len(payload)-1-i]
 | |
| 		good &^= mask&paddingLen ^ mask&b
 | |
| 	}
 | |
| 
 | |
| 	// We AND together the bits of good and replicate the result across
 | |
| 	// all the bits.
 | |
| 	good &= good << 4
 | |
| 	good &= good << 2
 | |
| 	good &= good << 1
 | |
| 	good = uint8(int8(good) >> 7)
 | |
| 
 | |
| 	toRemove = int(paddingLen) + 1
 | |
| 
 | |
| 	return toRemove, good
 | |
| }
 |