// Package common provides encryption methods common across encryption types
package common import ( ) // ZeroPad pads bytes with zeros to nearest multiple of message size m. func ( []byte, int) ([]byte, error) { if <= 0 { return nil, errors.New("Invalid message block size when padding") } if == nil || len() == 0 { return nil, errors.New("Data not valid to pad: Zero size") } if := len() % ; != 0 { := - := make([]byte, ) = append(, ...) } return , nil } // PKCS7Pad pads bytes according to RFC 2315 to nearest multiple of message size m. func ( []byte, int) ([]byte, error) { if <= 0 { return nil, errors.New("Invalid message block size when padding") } if == nil || len() == 0 { return nil, errors.New("Data not valid to pad: Zero size") } := - (len() % ) := make([]byte, len()+) copy(, ) copy([len():], bytes.Repeat([]byte{byte()}, )) return , nil } // PKCS7Unpad removes RFC 2315 padding from byes where message size is m. func ( []byte, int) ([]byte, error) { if <= 0 { return nil, errors.New("invalid message block size when unpadding") } if == nil || len() == 0 { return nil, errors.New("padded data not valid: Zero size") } if len()% != 0 { return nil, errors.New("padded data not valid: Not multiple of message block size") } := [len()-1] := int() if == 0 || > len() { return nil, errors.New("padded data not valid: Data may not have been padded") } for := 0; < ; ++ { if [len()-+] != { return nil, errors.New("padded data not valid") } } return [:len()-], nil } // GetHash generates the keyed hash value according to the etype's hash function. func (, []byte, []byte, etype.EType) ([]byte, error) { , := .DeriveKey(, ) if != nil { return nil, fmt.Errorf("unable to derive key for checksum: %v", ) } := hmac.New(.GetHashFunc(), ) := make([]byte, len()) copy(, ) .Write() return .Sum(nil)[:.GetHMACBitLength()/8], nil } // GetChecksumHash returns a keyed checksum hash of the bytes provided. func (, []byte, uint32, etype.EType) ([]byte, error) { return GetHash(, , GetUsageKc(), ) } // GetIntegrityHash returns a keyed integrity hash of the bytes provided. func (, []byte, uint32, etype.EType) ([]byte, error) { return GetHash(, , GetUsageKi(), ) } // VerifyChecksum compares the checksum of the msg bytes is the same as the checksum provided. func (, , []byte, uint32, etype.EType) bool { //The encrypted message is a concatenation of the encrypted output and the hash HMAC. , := GetChecksumHash(, , , ) return hmac.Equal(, ) } // GetUsageKc returns the checksum key usage value for the usage number un. // // See RFC 3961 5.3 key-derivation function definition. func ( uint32) []byte { return getUsage(, 0x99) } // GetUsageKe returns the encryption key usage value for the usage number un // // See RFC 3961 5.3 key-derivation function definition. func ( uint32) []byte { return getUsage(, 0xAA) } // GetUsageKi returns the integrity key usage value for the usage number un // // See RFC 3961 5.3 key-derivation function definition. func ( uint32) []byte { return getUsage(, 0x55) } func getUsage( uint32, byte) []byte { var bytes.Buffer binary.Write(&, binary.BigEndian, ) return append(.Bytes(), ) } // IterationsToS2Kparams converts the number of iterations as an integer to a string representation. func ( uint32) string { := make([]byte, 4, 4) binary.BigEndian.PutUint32(, ) return hex.EncodeToString() }