Documentation
¶
Overview ¶
Package crypto implements the cryptographic primitives used by the RADIUS protocol:
- Response Authenticator (RFC 2865 §3): MD5 over Code+ID+Length+RequestAuth+Attributes+Secret
- Accounting-Request Authenticator (RFC 2866 §3): MD5 over Code+ID+Length+16 zeros+Attributes+Secret
- User-Password hiding (RFC 2865 §5.2): chained MD5 + XOR
- Message-Authenticator (RFC 2869 §5.14): HMAC-MD5 over the entire packet
All functions are pure: callers pass the shared secret explicitly, and no state is retained. Constant-time comparison is used for verification paths.
Index ¶
- func ComputeAccountingRequestAuthenticator(code byte, id byte, length uint16, attributes []byte, secret []byte) [16]byte
- func ComputeMessageAuthenticator(packetBytes []byte, secret []byte) [16]byte
- func ComputeResponseAuthenticator(code byte, id byte, length uint16, requestAuth [16]byte, attributes []byte, ...) [16]byte
- func DecodeTunnelInteger(value []byte) (tag byte, hasTag bool, n uint32, err error)
- func DecodeTunnelTag(value []byte) (tag byte, hasTag bool, payload []byte)
- func DecryptTunnelPassword(value []byte, requestAuth [16]byte, secret []byte) (password []byte, tag byte, hasTag bool, err error)
- func DecryptUserPassword(ciphertext []byte, requestAuth [16]byte, secret []byte) ([]byte, error)
- func EncodeTunnelInteger(tag byte, n uint32) []byte
- func EncodeTunnelTag(tag byte) (byte, bool)
- func EncryptTunnelPassword(password []byte, requestAuth [16]byte, secret []byte, tag byte, hasTag bool) ([]byte, error)
- func EncryptUserPassword(password []byte, requestAuth [16]byte, secret []byte) ([]byte, error)
- func EqualConstantTime(a, b []byte) bool
- func VerifyMessageAuthenticator(packetBytes []byte, received [16]byte, secret []byte) bool
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComputeAccountingRequestAuthenticator ¶
func ComputeAccountingRequestAuthenticator(code byte, id byte, length uint16, attributes []byte, secret []byte) [16]byte
ComputeAccountingRequestAuthenticator calculates the Request Authenticator for an Accounting-Request packet (RFC 2866 §3).
Unlike Access-Request (which uses a random value), the Accounting-Request authenticator is itself an MD5 digest because there is no User-Password attribute to hide:
MD5(Code + ID + Length + 16 zero octets + Attributes + Secret)
func ComputeMessageAuthenticator ¶
ComputeMessageAuthenticator calculates the HMAC-MD5 Message-Authenticator (RFC 2869 §5.14) over an entire RADIUS packet.
The caller MUST zero the 16-octet Value field of the Message-Authenticator attribute within packetBytes before calling this function. The returned digest is written into that field by the packet codec.
The shared secret is used as the HMAC key.
func ComputeResponseAuthenticator ¶
func ComputeResponseAuthenticator(code byte, id byte, length uint16, requestAuth [16]byte, attributes []byte, secret []byte) [16]byte
ComputeResponseAuthenticator calculates the Response Authenticator used by Access-Accept, Access-Reject, Access-Challenge (RFC 2865 §3), and Accounting-Response (RFC 2866 §3).
Formula: MD5(Code + ID + Length + RequestAuth + Attributes + Secret) where Length is big-endian uint16 and RequestAuth is the 16-byte Request Authenticator from the corresponding request packet.
func DecodeTunnelInteger ¶
DecodeTunnelInteger decodes a tagged integer tunnel attribute. Returns the tag (or 0 with hasTag=false when no tag prefix is present) and the integer value.
Ambiguity note: RFC 2868 §3.1 lets integer tunnel attributes omit the tag. When the first byte of the value falls in 0x01..0x1F the decoder cannot tell whether it is a tag or the high byte of the integer. Callers that know from context whether a tag is present should validate accordingly; this helper follows the spec's literal "0x01..0x1F means tag" rule.
func DecodeTunnelTag ¶
DecodeTunnelTag returns the tag and the remaining value bytes from a tagged tunnel attribute Value. If the first byte is in 0x00..0x1F it is treated as a tag and the rest is the payload; otherwise the entire Value is the payload and hasTag=false.
Per RFC 2868 §3.1 the tag field is optional: a first byte in 0x20..0xFF is the start of the actual data, not a tag.
func DecryptTunnelPassword ¶
func DecryptTunnelPassword(value []byte, requestAuth [16]byte, secret []byte) (password []byte, tag byte, hasTag bool, err error)
DecryptTunnelPassword reverses EncryptTunnelPassword. value is the Tunnel-Password attribute Value (Salt [+ tag] + encrypted password). requestAuth is the Request Authenticator of the enclosing Access-Request.
Returns the plaintext password (with NUL padding stripped) and, when present, the tag and hasTag=true.
func DecryptUserPassword ¶
DecryptUserPassword reverses EncryptUserPassword. The ciphertext length must be a non-zero multiple of 16 and at most 128 octets. Trailing NUL padding introduced during encryption is stripped from the returned plaintext.
func EncodeTunnelInteger ¶
EncodeTunnelInteger encodes a tagged integer tunnel attribute (Tunnel-Type, Tunnel-Medium-Type, Tunnel-Preference) per RFC 2868 §3.1. The wire layout is: [Tag] + 4-byte big-endian integer. When tag is 0 the prefix is omitted.
func EncodeTunnelTag ¶
EncodeTunnelTag encodes a 1-byte tag prefix for a tagged tunnel attribute per RFC 2868 §3.1. Tags 0x01..0x1F are valid; tag 0x00 means "no tag" and the returned ok=false signals the caller to omit the prefix.
func EncryptTunnelPassword ¶
func EncryptTunnelPassword(password []byte, requestAuth [16]byte, secret []byte, tag byte, hasTag bool) ([]byte, error)
EncryptTunnelPassword encrypts a tunnel password per RFC 2868 §3.3. requestAuth is the 16-byte Request Authenticator from the enclosing Access-Request packet. tag is the optional 1-byte tunnel tag; pass hasTag=false to omit it. When hasTag is true, tag MUST be in 0x01..0x1F.
Returns the Value field (Salt + encrypted password, with the tag flag baked into the Salt's high bit) ready to be placed in a Tunnel-Password attribute.
func EncryptUserPassword ¶
EncryptUserPassword hides a cleartext password using the RFC 2865 §5.2 algorithm: the password is null-padded to a 16-byte boundary, then each 16-octet block is XORed with MD5(secret || previous_ciphertext_block), where the first block uses the Request Authenticator as the previous block.
The result length is a multiple of 16, between 16 and 128 octets inclusive. Returns ErrPasswordTooLong if len(password) > 128, and ErrSecretEmpty if the shared secret is empty.
func EqualConstantTime ¶
EqualConstantTime reports whether a and b are byte-for-byte equal without leaking timing information about the position of the first difference. Returns false when lengths differ.
func VerifyMessageAuthenticator ¶
VerifyMessageAuthenticator recomputes the HMAC-MD5 over packetBytes and compares it against received in constant time. As with ComputeMessageAuthenticator, the Value field of the Message-Authenticator attribute in packetBytes must be zeroed before calling.
Types ¶
This section is empty.