MCPcopy
hub / github.com/XTLS/REALITY / encrypt

Method encrypt

conn.go:487–597  ·  view source on GitHub ↗

encrypt encrypts payload, adding the appropriate nonce and/or MAC, and appends it to record, which must already contain the record header.

(record, payload []byte, rand io.Reader)

Source from the content-addressed store, hash-verified

485// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
486// appends it to record, which must already contain the record header.
487func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {
488 if hc.cipher == nil {
489 return append(record, payload...), nil
490 }
491
492 var explicitNonce []byte
493 if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {
494 record, explicitNonce = sliceForAppend(record, explicitNonceLen)
495 if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {
496 // The AES-GCM construction in TLS has an explicit nonce so that the
497 // nonce can be random. However, the nonce is only 8 bytes which is
498 // too small for a secure, random nonce. Therefore we use the
499 // sequence number as the nonce. The 3DES-CBC construction also has
500 // an 8 bytes nonce but its nonces must be unpredictable (see RFC
501 // 5246, Appendix F.3), forcing us to use randomness. That's not
502 // 3DES' biggest problem anyway because the birthday bound on block
503 // collision is reached first due to its similarly small block size
504 // (see the Sweet32 attack).
505 copy(explicitNonce, hc.seq[:])
506 } else {
507 if _, err := io.ReadFull(rand, explicitNonce); err != nil {
508 return nil, err
509 }
510 }
511 }
512
513 var dst []byte
514 switch c := hc.cipher.(type) {
515 case cipher.Stream:
516 mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
517 record, dst = sliceForAppend(record, len(payload)+len(mac))
518 c.XORKeyStream(dst[:len(payload)], payload)
519 c.XORKeyStream(dst[len(payload):], mac)
520 case aead:
521 nonce := explicitNonce
522 if len(nonce) == 0 {
523 nonce = hc.seq[:]
524 }
525
526 if hc.version == VersionTLS13 {
527 record = append(record, payload...)
528
529 // Encrypt the actual ContentType and replace the plaintext one.
530 record = append(record, record[0])
531 padding := 0
532 if recordType(record[0]) == recordTypeHandshake && hc.handshakeLen[1] != 0 {
533 switch payload[0] {
534 case typeEncryptedExtensions:
535 padding = hc.handshakeLen[2]
536 hc.handshakeLen[2] = 0
537 case typeCertificate:
538 padding = hc.handshakeLen[3]
539 hc.handshakeLen[3] = 0
540 case typeCertificateVerify:
541 padding = hc.handshakeLen[4]
542 hc.handshakeLen[4] = 0
543 case typeFinished:
544 padding = hc.handshakeLen[5]

Callers 1

writeRecordLockedMethod · 0.80

Calls 9

explicitNonceLenMethod · 0.95
incSeqMethod · 0.95
sliceForAppendFunction · 0.85
tls10MACFunction · 0.85
recordTypeTypeAlias · 0.85
BlockSizeMethod · 0.80
SetIVMethod · 0.80
OverheadMethod · 0.45
SealMethod · 0.45

Tested by

no test coverage detected