func GetHash(a string) (hash.Hash, error) { var h hash.Hash switch a { case "adler32": h = adler32.New() case "crc32", "crc32ieee": h = crc32.New(crc32.MakeTable(crc32.IEEE)) case "crc32castagnoli": h = crc32.New(crc32.MakeTable(crc32.Castagnoli)) case "crc32koopman": h = crc32.New(crc32.MakeTable(crc32.Koopman)) case "crc64", "crc64iso": h = crc64.New(crc64.MakeTable(crc64.ISO)) case "crc64ecma": h = crc64.New(crc64.MakeTable(crc64.ECMA)) case "fnv", "fnv32": h = fnv.New32() case "fnv32a": h = fnv.New32a() case "fnv64": h = fnv.New64() case "fnv64a": h = fnv.New64a() case "hmac", "hmacsha256": h = hmac.New(sha256.New, []byte(key)) case "hmacmd5": h = hmac.New(md5.New, []byte(key)) case "hmacsha1": h = hmac.New(sha1.New, []byte(key)) case "hmacsha512": h = hmac.New(sha512.New, []byte(key)) case "md4": h = md4.New() case "md5": h = md5.New() case "ripemd160": h = ripemd160.New() case "sha1": h = sha1.New() case "sha224": h = sha256.New224() case "sha256": h = sha256.New() case "sha384": h = sha512.New384() case "sha512": h = sha512.New() default: return nil, errors.New("Invalid algorithm") } return h, nil }
func makeBlob(blobPart []byte, keys privateKeys, publicKey string) string { part := []byte(base64.StdEncoding.EncodeToString(blobPart)) sharedKey := keys.SharedKey(publicKey) iv := randomVec(16) key := sha1.Sum(sharedKey) base_key := key[:16] hash := hmac.New(sha1.New, base_key) hash.Write([]byte("checksum")) checksum_key := hash.Sum(nil) hash.Reset() hash.Write([]byte("encryption")) encryption_key := hash.Sum(nil) hash.Reset() block, _ := aes.NewCipher(encryption_key[0:16]) stream := cipher.NewCTR(block, iv) stream.XORKeyStream(part, part) macHash := hmac.New(sha1.New, checksum_key) macHash.Write(part) mac := macHash.Sum(nil) part = append(iv, part...) part = append(part, mac...) return base64.StdEncoding.EncodeToString(part) }
//Password returns the password for the given website, password version and templates func (algo *Algorithm) Password(site string, version string, templates []string) (string, error) { if len(templates) < 1 { return "", fmt.Errorf("%s", "invalid template") } h := hmac.New(sha512.New, algo.key) if algo.variant == 0 { h = hmac.New(sha256.New, algo.key) } _, err := h.Write([]byte(fmt.Sprint(string(algo.saltPrefix), uint32(len(site)), site, version))) if err != nil { return "", err } seed := h.Sum(nil) template := templates[uint32(seed[0])%uint32(len(templates))] password := []byte(template) for i, tplRune := range template { var passchars string switch tplRune { case 'V': passchars = V case 'C': passchars = C case 'v': passchars = v case 'c': passchars = c case 'A': passchars = A case 'a': passchars = a case 'n': passchars = n case 'o': passchars = o case 'X': passchars = X case 'x': passchars = x case 'p': passchars = p default: return "", fmt.Errorf("%s", "invalid template") } if i+1 < len(seed) { password[i] = passchars[uint32(seed[i+1])%uint32(len(passchars))] } else { password[i] = passchars[0] } } return string(password), err }
func Sign(credentials *BceCredentials, timestamp, httpMethod, path, query string, headers map[string]string) string { if path[0] != '/' { path = "/" + path } var expirationPeriodInSeconds = 1800 authStringPrefix := fmt.Sprintf("bce-auth-v1/%s/%s/%d", credentials.AccessKeyId, timestamp, expirationPeriodInSeconds) //fmt.Println(authStringPrefix) mac := hmac.New(sha256.New, []byte(credentials.SecretAccessKey)) mac.Write([]byte(authStringPrefix)) signingKey := fmt.Sprintf("%x", mac.Sum(nil)) //fmt.Printf(signingKey) CanonicalURI := utils.UriEncodeExceptSlash(path) CanonicalQueryString := getCannonicalQuery(query) CanonicalHeaders, signedHeaders := getCanonicalHeaders(headers, nil) CanonicalRequest := fmt.Sprintf("%s\n%s\n%s\n%s", httpMethod, CanonicalURI, CanonicalQueryString, CanonicalHeaders) mac = hmac.New(sha256.New, []byte(signingKey)) mac.Write([]byte(CanonicalRequest)) signature := fmt.Sprintf("%x", mac.Sum(nil)) //fmt.Println(signature) authorization := fmt.Sprintf("%s/%s/%s", authStringPrefix, signedHeaders, signature) if Debug { fmt.Println(CanonicalRequest) fmt.Println(authorization) } return authorization }
func getSignature(b []byte, secret []byte) []byte { keym := hmac.New(sha256.New, secret) keym.Write(b) m := hmac.New(sha256.New, keym.Sum(nil)) m.Write(b) return m.Sum(nil) }
// Returns true if the provided message is unsigned or has a valid signature // from one of the provided signers. func authenticateMessage(signers map[string]Signer, header *Header, msg []byte) bool { digest := header.GetHmac() if digest != nil { var key string signer := fmt.Sprintf("%s_%d", header.GetHmacSigner(), header.GetHmacKeyVersion()) if s, ok := signers[signer]; ok { key = s.HmacKey } else { return false } var hm hash.Hash switch header.GetHmacHashFunction() { case Header_MD5: hm = hmac.New(md5.New, []byte(key)) case Header_SHA1: hm = hmac.New(sha1.New, []byte(key)) } hm.Write(msg) expectedDigest := hm.Sum(nil) if subtle.ConstantTimeCompare(digest, expectedDigest) != 1 { return false } } return true }
func (p *PrivateKeys) addRemoteKey(remote []byte, clientPacket []byte, serverPacket []byte) SharedKeys { remote_be := new(big.Int) remote_be.SetBytes(remote) shared_key := powm(remote_be, p.privateKey, p.prime) data := make([]byte, 0, 100) mac := hmac.New(sha1.New, shared_key.Bytes()) for i := 1; i < 6; i++ { mac.Write(clientPacket) mac.Write(serverPacket) mac.Write([]byte{uint8(i)}) data = append(data, mac.Sum(nil)...) mac.Reset() } mac = hmac.New(sha1.New, data[0:0x14]) mac.Write(clientPacket) mac.Write(serverPacket) return SharedKeys{ challenge: mac.Sum(nil), sendKey: data[0x14:0x34], recvKey: data[0x34:0x54], } }
// CheckMAC returns true if messageMAC is a valid HMAC tag for message. func CheckMAC(message []byte, messageMAC string, key string) bool { var err error var mac hash.Hash var macdata []byte var macparts = strings.Split(messageMAC, "=") macdata, err = hex.DecodeString(macparts[1]) if err != nil { log.Print("Error decoding hex digest: ", err) return false } switch macparts[0] { case "md5": mac = hmac.New(md5.New, []byte(key)) case "sha1": mac = hmac.New(sha1.New, []byte(key)) case "sha256": mac = hmac.New(sha256.New, []byte(key)) case "sha512": mac = hmac.New(sha512.New, []byte(key)) default: log.Print("Unsupported hash: ", macparts[0]) return false } mac.Write(message) expectedMAC := mac.Sum(nil) return hmac.Equal(macdata, expectedMAC) }
func authenticateMessage(signers map[string]Signer, header *Header, pack *PipelinePack) bool { digest := header.GetHmac() if digest != nil { var key string signer := fmt.Sprintf("%s_%d", header.GetHmacSigner(), header.GetHmacKeyVersion()) if s, ok := signers[signer]; ok { key = s.HmacKey } else { return false } var hm hash.Hash switch header.GetHmacHashFunction() { case Header_MD5: hm = hmac.New(md5.New, []byte(key)) case Header_SHA1: hm = hmac.New(sha1.New, []byte(key)) } hm.Write(pack.MsgBytes) expectedDigest := hm.Sum(nil) if bytes.Compare(digest, expectedDigest) != 0 { return false } pack.Signer = header.GetHmacSigner() } return true }
// TsigVerify verifies the TSIG on a message. // If the signature does not validate err contains the // error, otherwise it is nil. func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error { rawsecret, err := packBase64([]byte(secret)) if err != nil { return err } // Srtip the TSIG from the incoming msg stripped, tsig, err := stripTsig(msg) if err != nil { return err } buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly) ti := uint64(time.Now().Unix()) - tsig.TimeSigned if uint64(tsig.Fudge) < ti { return ErrTime } var h hash.Hash switch tsig.Algorithm { case HmacMD5: h = hmac.New(md5.New, []byte(rawsecret)) case HmacSHA1: h = hmac.New(sha1.New, []byte(rawsecret)) case HmacSHA256: h = hmac.New(sha256.New, []byte(rawsecret)) default: return ErrKeyAlg } io.WriteString(h, string(buf)) if strings.ToUpper(hex.EncodeToString(h.Sum(nil))) != strings.ToUpper(tsig.MAC) { return ErrSig } return nil }
func TestDerivededSigningKey(t *testing.T) { t.Parallel() os.Setenv("PWNIE_SECRET_KEY", "foobar") os.Setenv("PWNIE_REGION", "us-east-1") req := newRequest() mac := hmac.New(sha256.New, []byte("AWS4foobar")) mac.Write([]byte(formatShortDate(time.Now().UTC()))) kDate := mac.Sum(nil) mac = hmac.New(sha256.New, kDate) mac.Write([]byte(viper.GetString("region"))) kRegion := mac.Sum(nil) mac = hmac.New(sha256.New, kRegion) mac.Write([]byte("www")) kService := mac.Sum(nil) mac = hmac.New(sha256.New, kService) mac.Write([]byte("aws4_request")) kSigning := mac.Sum(nil) expected := kSigning actual := req.DerivedSigningKey() if !hmac.Equal(expected, actual) { t.Errorf("\n%v\n != \n%v", actual, expected) } }
// lionDecode performs the inverse operation of lionessEncode. Namely, // decrypting a previously generated cipher text, returning the original plaintext. func lionessDecode(key [securityParameter]byte, cipherText [messageSize]byte) [messageSize]byte { var message [messageSize]byte copy(message[:], cipherText[:]) L := message[:securityParameter] R := message[securityParameter:] // Round 4. // R = R XOR S(L XOR K_4) var k4 [securityParameter]byte xor(k4[:], L[:], key[:]) xor(R[:], R[:], generateCipherStream(k4, uint(len(R)))) // Round 3. // L = L XOR H_k3(R) h := hmac.New(sha256.New, append(key[:], 0x03)) h.Write(R) xor(L[:], h.Sum(nil)[:securityParameter], L[:]) // Round 2. // R = R XOR S(L XOR K_2) var k2 [securityParameter]byte xor(k2[:], L[:], key[:]) xor(R[:], R[:], generateCipherStream(k2, uint(len(R)))) // Round 1. // L = L XOR H_k1(R) h = hmac.New(sha256.New, append(key[:], 0x01)) h.Write(R) xor(L[:], h.Sum(nil)[:securityParameter], L[:]) return message }
// Child returns the ith child of wallet w. Values of i >= 2^31 // signify private key derivation. Attempting private key derivation // with a public key will throw an error. func (w *HDWallet) Child(i uint32) (*HDWallet, error) { var fingerprint, I, newkey []byte switch { case bytes.Compare(w.Vbytes, Private) == 0, bytes.Compare(w.Vbytes, TestPrivate) == 0: pub := privToPub(w.Key) mac := hmac.New(sha512.New, w.Chaincode) if i >= uint32(0x80000000) { mac.Write(append(w.Key, uint32ToByte(i)...)) } else { mac.Write(append(pub, uint32ToByte(i)...)) } I = mac.Sum(nil) iL := new(big.Int).SetBytes(I[:32]) if iL.Cmp(curve.N) >= 0 || iL.Sign() == 0 { return &HDWallet{}, errors.New("Invalid Child") } newkey = addPrivKeys(I[:32], w.Key) fingerprint = hash160(privToPub(w.Key))[:4] case bytes.Compare(w.Vbytes, Public) == 0, bytes.Compare(w.Vbytes, TestPublic) == 0: mac := hmac.New(sha512.New, w.Chaincode) if i >= uint32(0x80000000) { return &HDWallet{}, errors.New("Can't do Private derivation on Public key!") } mac.Write(append(w.Key, uint32ToByte(i)...)) I = mac.Sum(nil) iL := new(big.Int).SetBytes(I[:32]) if iL.Cmp(curve.N) >= 0 || iL.Sign() == 0 { return &HDWallet{}, errors.New("Invalid Child") } newkey = addPubKeys(privToPub(I[:32]), w.Key) fingerprint = hash160(w.Key)[:4] } return &HDWallet{w.Vbytes, w.Depth + 1, fingerprint, uint32ToByte(i), I[32:], newkey}, nil }
func (conn *obfs3Conn) kdf(sharedSecret []byte) error { // Using that shared-secret each party derives its encryption keys as // follows: // // INIT_SECRET = HMAC(SHARED_SECRET, "Initiator obfuscated data") // RESP_SECRET = HMAC(SHARED_SECRET, "Responder obfuscated data") // INIT_KEY = INIT_SECRET[:KEYLEN] // INIT_COUNTER = INIT_SECRET[KEYLEN:] // RESP_KEY = RESP_SECRET[:KEYLEN] // RESP_COUNTER = RESP_SECRET[KEYLEN:] initHmac := hmac.New(sha256.New, sharedSecret) initHmac.Write([]byte(initiatorKdfString)) initSecret := initHmac.Sum(nil) initHmac.Reset() initHmac.Write([]byte(initiatorMagicString)) initMagic := initHmac.Sum(nil) respHmac := hmac.New(sha256.New, sharedSecret) respHmac.Write([]byte(responderKdfString)) respSecret := respHmac.Sum(nil) respHmac.Reset() respHmac.Write([]byte(responderMagicString)) respMagic := respHmac.Sum(nil) // The INIT_KEY value keys a block cipher (in CTR mode) used to // encrypt values from initiator to responder thereafter. The counter // mode's initial counter value is INIT_COUNTER. The RESP_KEY value // keys a block cipher (in CTR mode) used to encrypt values from // responder to initiator thereafter. That counter mode's initial // counter value is RESP_COUNTER. // // Note: To have this be the last place where the shared secret is used, // also generate the magic value to send/scan for here. initBlock, err := aes.NewCipher(initSecret[:keyLen]) if err != nil { return err } initStream := cipher.NewCTR(initBlock, initSecret[keyLen:]) respBlock, err := aes.NewCipher(respSecret[:keyLen]) if err != nil { return err } respStream := cipher.NewCTR(respBlock, respSecret[keyLen:]) if conn.isInitiator { conn.tx = &cipher.StreamWriter{S: initStream, W: conn.Conn} conn.rx = &cipher.StreamReader{S: respStream, R: conn.rxBuf} conn.txMagic = initMagic conn.rxMagic = respMagic } else { conn.tx = &cipher.StreamWriter{S: respStream, W: conn.Conn} conn.rx = &cipher.StreamReader{S: initStream, R: conn.rxBuf} conn.txMagic = respMagic conn.rxMagic = initMagic } return nil }
func (creds *Credentials) MAC() hash.Hash { if creds.Hash != nil { return hmac.New(creds.Hash, []byte(creds.Key)) } else { // use a default hash return hmac.New(sha256.New, []byte(creds.Key)) } }
func TestTOTP(t *testing.T) { keySha1, err := hex.DecodeString(sha1KeyHex) checkError(t, err) keySha256, err := hex.DecodeString(sha256KeyHex) checkError(t, err) keySha512, err := hex.DecodeString(sha512KeyHex) checkError(t, err) // create the OTP otp := new(Totp) otp.digits = 8 otp.issuer = "Sec51" otp.account = "*****@*****.**" // Test SHA1 otp.key = keySha1 for index, ts := range timeCounters { counter := increment(ts, 30) otp.counter = bigendian.ToUint64(counter) hash := hmac.New(sha1.New, otp.key) token := calculateToken(otp.counter[:], otp.digits, hash) expected := sha1TestData[index] if token != expected { t.Errorf("SHA1 test data, token mismatch. Got %s, expected %s\n", token, expected) } } // Test SHA256 otp.key = keySha256 for index, ts := range timeCounters { counter := increment(ts, 30) otp.counter = bigendian.ToUint64(counter) hash := hmac.New(sha256.New, otp.key) token := calculateToken(otp.counter[:], otp.digits, hash) expected := sha256TestData[index] if token != expected { t.Errorf("SHA256 test data, token mismatch. Got %s, expected %s\n", token, expected) } } // Test SHA512 otp.key = keySha512 for index, ts := range timeCounters { counter := increment(ts, 30) otp.counter = bigendian.ToUint64(counter) hash := hmac.New(sha512.New, otp.key) token := calculateToken(otp.counter[:], otp.digits, hash) expected := sha512TestData[index] if token != expected { t.Errorf("SHA512 test data, token mismatch. Got %s, expected %s\n", token, expected) } } }
func makeMac(hashType string, key []byte) (hash.Hash, int) { switch hashType { case "SHA1": return hmac.New(sha1.New, key), sha1.Size case "SHA512": return hmac.New(sha512.New, key), sha512.Size default: return hmac.New(sha256.New, key), sha256.Size } }
// MAC hash helper function func macHash(algo, secKey, normalized string) []byte { var h hash.Hash if algo == "sha1" { h = hmac.New(sha1.New, []byte(secKey)) } else { h = hmac.New(sha256.New, []byte(secKey)) } h.Write([]byte(normalized)) return h.Sum(nil) }
// New returns a new HKDF using the given hash, the secret keying material to expand // and optional salt and info fields. func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader { if salt == nil { salt = make([]byte, hash().Size()) } extractor := hmac.New(hash, salt) extractor.Write(secret) prk := extractor.Sum(nil) return &hkdf{hmac.New(hash, prk), extractor.Size(), info, 1, nil, nil} }
func callbackGoogleGet(c *gin.Context) { db := c.MustGet("db").(*database.Database) params := utils.ParseParams(c.Request) state := params.GetByName("state") code := params.GetByName("code") authErr := params.GetByName("error") switch authErr { case "": if state == "" || code == "" { c.AbortWithStatus(400) return } case "access_denied": // TODO Redirect to base callback url c.Redirect(301, "https://pritunl.com/") return default: c.AbortWithStatus(400) return } acct, tokn, err := google.Authorize(db, state, code) if err != nil { c.AbortWithError(500, err) return } if tokn.Version == 1 { query := fmt.Sprintf("state=%s&username=%s", tokn.RemoteState, url.QueryEscape(acct.Id)) hashFunc := hmac.New(sha512.New, []byte(tokn.RemoteSecret)) hashFunc.Write([]byte(query)) rawSignature := hashFunc.Sum(nil) sig := base64.URLEncoding.EncodeToString(rawSignature) url := fmt.Sprintf("%s?%s&sig=%s", tokn.RemoteCallback, query, url.QueryEscape(sig)) c.Redirect(301, url) } else { hashFunc := hmac.New(sha256.New, []byte(tokn.RemoteSecret)) hashFunc.Write([]byte(tokn.RemoteState + acct.Id)) rawSignature := hashFunc.Sum(nil) sig := base64.URLEncoding.EncodeToString(rawSignature) c.Redirect(301, fmt.Sprintf("%s?state=%s&user=%s&sig=%s", tokn.RemoteCallback, tokn.RemoteState, url.QueryEscape(acct.Id), sig)) } }
func (c *connectionHandshakeV1_0) serverSignature(saltedPass []byte) string { mac := hmac.New(c.hashFunc(), saltedPass) mac.Write([]byte("Server Key")) serverKey := mac.Sum(nil) mac = hmac.New(c.hashFunc(), serverKey) mac.Write([]byte(c.authMsg)) serverSignature := mac.Sum(nil) return base64.StdEncoding.EncodeToString(serverSignature) }
// TsigGenerate fills out the TSIG record attached to the message. // The message should contain // a "stub" TSIG RR with the algorithm, key name (owner name of the RR), // time fudge (defaults to 300 seconds) and the current time // The TSIG MAC is saved in that Tsig RR. // When TsigGenerate is called for the first time requestMAC is set to the empty string and // timersOnly is false. // If something goes wrong an error is returned, otherwise it is nil. func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { if m.IsTsig() == nil { panic("dns: TSIG not last RR in additional") } // If we barf here, the caller is to blame rawsecret, err := fromBase64([]byte(secret)) if err != nil { return nil, "", err } rr := m.Extra[len(m.Extra)-1].(*TSIG) m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg mbuf, err := m.Pack() if err != nil { return nil, "", err } buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly) t := new(TSIG) var h hash.Hash switch strings.ToLower(rr.Algorithm) { case HmacMD5: h = hmac.New(md5.New, []byte(rawsecret)) case HmacSHA1: h = hmac.New(sha1.New, []byte(rawsecret)) case HmacSHA256: h = hmac.New(sha256.New, []byte(rawsecret)) case HmacSHA512: h = hmac.New(sha512.New, []byte(rawsecret)) default: return nil, "", ErrKeyAlg } io.WriteString(h, string(buf)) t.MAC = hex.EncodeToString(h.Sum(nil)) t.MACSize = uint16(len(t.MAC) / 2) // Size is half! t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0} t.Fudge = rr.Fudge t.TimeSigned = rr.TimeSigned t.Algorithm = rr.Algorithm t.OrigId = m.Id tbuf := make([]byte, t.len()) if off, err := PackRR(t, tbuf, 0, nil, false); err == nil { tbuf = tbuf[:off] // reset to actual size used } else { return nil, "", err } mbuf = append(mbuf, tbuf...) // Update the ArCount directly in the buffer. binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1)) return mbuf, t.MAC, nil }
func newMac(hashType string, key []byte) (HMAC, error) { switch hashType { case "SHA1": return HMAC{hmac.New(sha1.New, key), sha1.Size}, nil case "SHA512": return HMAC{hmac.New(sha512.New, key), sha512.Size}, nil case "SHA256": return HMAC{hmac.New(sha256.New, key), sha256.Size}, nil default: return HMAC{}, fmt.Errorf("Unrecognized hash type: %s", hashType) } }
// HMAC test vectors taken from // http://tc26.ru/methods/recommendation/%D0%A2%D0%9A26%D0%90%D0%9B%D0%93.pdf test vectors func TestHMACVectors(t *testing.T) { h := hmac.New(hash256, []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}) h.Write([]byte{0x01, 0x26, 0xbd, 0xb8, 0x78, 0x00, 0xaf, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78, 0x01, 0x00}) if bytes.Compare(h.Sum(nil), []byte{0xa1, 0xaa, 0x5f, 0x7d, 0xe4, 0x02, 0xd7, 0xb3, 0xd3, 0x23, 0xf2, 0x99, 0x1c, 0x8d, 0x45, 0x34, 0x01, 0x31, 0x37, 0x01, 0x0a, 0x83, 0x75, 0x4f, 0xd0, 0xaf, 0x6d, 0x7c, 0xd4, 0x92, 0x2e, 0xd9}) != 0 { t.Fail() } h = hmac.New(hash512, []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}) h.Write([]byte{0x01, 0x26, 0xbd, 0xb8, 0x78, 0x00, 0xaf, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78, 0x01, 0x00}) if bytes.Compare(h.Sum(nil), []byte{0xa5, 0x9b, 0xab, 0x22, 0xec, 0xae, 0x19, 0xc6, 0x5f, 0xbd, 0xe6, 0xe5, 0xf4, 0xe9, 0xf5, 0xd8, 0x54, 0x9d, 0x31, 0xf0, 0x37, 0xf9, 0xdf, 0x9b, 0x90, 0x55, 0x00, 0xe1, 0x71, 0x92, 0x3a, 0x77, 0x3d, 0x5f, 0x15, 0x30, 0xf2, 0xed, 0x7e, 0x96, 0x4c, 0xb2, 0xee, 0xdc, 0x29, 0xe9, 0xad, 0x2f, 0x3a, 0xfe, 0x93, 0xb2, 0x81, 0x4f, 0x79, 0xf5, 0x00, 0x0f, 0xfc, 0x03, 0x66, 0xc2, 0x51, 0xe6}) != 0 { t.Fail() } }
func (c *Client) serverSignature() []byte { mac := hmac.New(c.newHash, c.saltedPass) mac.Write([]byte("Server Key")) serverKey := mac.Sum(nil) mac = hmac.New(c.newHash, serverKey) mac.Write(c.authMsg.Bytes()) serverSignature := mac.Sum(nil) encoded := make([]byte, b64.EncodedLen(len(serverSignature))) b64.Encode(encoded, serverSignature) return encoded }
func CreateHekaStream(msgBytes []byte, outBytes *[]byte, msc *message.MessageSigningConfig) error { msgSize := uint32(len(msgBytes)) if msgSize > message.MAX_MESSAGE_SIZE { return fmt.Errorf("Message too big, requires %d (MAX_MESSAGE_SIZE = %d)", len(msgBytes), message.MAX_MESSAGE_SIZE) } h := &message.Header{} h.SetMessageLength(msgSize) if msc != nil { h.SetHmacSigner(msc.Name) h.SetHmacKeyVersion(msc.Version) var hm hash.Hash switch msc.Hash { case "sha1": hm = hmac.New(sha1.New, []byte(msc.Key)) h.SetHmacHashFunction(message.Header_SHA1) default: hm = hmac.New(md5.New, []byte(msc.Key)) } hm.Write(msgBytes) h.SetHmac(hm.Sum(nil)) } headerSize := proto.Size(h) if headerSize > message.MAX_HEADER_SIZE { return fmt.Errorf("Message header too big, requires %d (MAX_HEADER_SIZE = %d)", headerSize, message.MAX_HEADER_SIZE) } requiredSize := message.HEADER_FRAMING_SIZE + headerSize + len(msgBytes) if cap(*outBytes) < requiredSize { *outBytes = make([]byte, requiredSize) } else { *outBytes = (*outBytes)[:requiredSize] } (*outBytes)[0] = message.RECORD_SEPARATOR (*outBytes)[1] = uint8(headerSize) // This looks odd but is correct; it effectively "seeks" the initial write // position for the protobuf output to be at the // `(*outBytes)[message.HEADER_DELIMITER_SIZE]` position. pbuf := proto.NewBuffer((*outBytes)[message.HEADER_DELIMITER_SIZE:message.HEADER_DELIMITER_SIZE]) if err := pbuf.Marshal(h); err != nil { return err } (*outBytes)[headerSize+message.HEADER_DELIMITER_SIZE] = message.UNIT_SEPARATOR copy((*outBytes)[message.HEADER_FRAMING_SIZE+headerSize:], msgBytes) return nil }
func (c *Conversation) processEncryptedSig(encryptedSig, theirMAC []byte, keys *akeKeys, xFirst bool) error { mac := hmac.New(sha256.New, keys.m2[:]) mac.Write(appendData(nil, encryptedSig)) myMAC := mac.Sum(nil)[:20] if len(myMAC) != len(theirMAC) || subtle.ConstantTimeCompare(myMAC, theirMAC) == 0 { return errors.New("bad signature MAC in encrypted signature") } aesCipher, err := aes.NewCipher(keys.c[:]) if err != nil { panic(err.Error()) } var iv [aes.BlockSize]byte ctr := cipher.NewCTR(aesCipher, iv[:]) ctr.XORKeyStream(encryptedSig, encryptedSig) sig := encryptedSig sig, ok1 := c.TheirPublicKey.Parse(sig) keyId, sig, ok2 := getU32(sig) if !ok1 || !ok2 { return errors.New("otr: corrupt encrypted signature") } var verifyData []byte if xFirst { verifyData = appendMPI(verifyData, c.gx) verifyData = appendMPI(verifyData, c.gy) } else { verifyData = appendMPI(verifyData, c.gy) verifyData = appendMPI(verifyData, c.gx) } verifyData = c.TheirPublicKey.Serialize(verifyData) verifyData = appendU32(verifyData, keyId) mac = hmac.New(sha256.New, keys.m1[:]) mac.Write(verifyData) mb := mac.Sum(nil) sig, ok1 = c.TheirPublicKey.Verify(mb, sig) if !ok1 { return errors.New("bad signature in encrypted signature") } if len(sig) > 0 { return errors.New("corrupt encrypted signature") } c.theirKeyId = keyId zero(c.theirLastCtr[:]) return nil }
func newEncReader(r io.Reader, secrets *Secrets, length int) (reader *encReader, err error) { buf := make([]byte, 48) n, err := r.Read(buf[:1]) if n != 1 { return nil, fmt.Errorf("Error decoding chunk") } if err != nil { return nil, err } version := buf[0] if version != 0 { return nil, fmt.Errorf("Unsupported chunk version %d", version) } n, err = r.Read(buf) if n != 48 { return nil, fmt.Errorf("Error decoding chunk") } if err != nil { return nil, err } nonce := make([]byte, 48) copy(nonce, buf) digester := hmac.New(sha512.New384, secrets.chunkMaster) digester.Write([]byte("\000chunk encryption\000")) digester.Write(nonce) digester.Write([]byte{0x01, 0x80}) derivedKey := digester.Sum(nil) key := derivedKey[0:32] iv := derivedKey[32:48] aesCypher, err := aes.NewCipher(key) if err != nil { return nil, err } cypher := cipher.NewCTR(aesCypher, iv) authHMAC := hmac.New(sha512.New384, secrets.chunkAuthentication) authHMAC.Write([]byte{0}) authHMAC.Write(nonce) authHMAC.Write(key) authHMAC.Write(iv) cypherStream := cipher.StreamReader{S: cypher, R: io.TeeReader(r, authHMAC)} n, err = cypherStream.Read(buf[0:1]) if n != 1 { return nil, fmt.Errorf("Error decoding chunk") } if err != nil { return nil, err } //compressed_p := buf[0] != 0 return &encReader{source: r, reader: cypherStream, authHMAC: authHMAC, length: length - 48, numRead: 50}, nil }
// TsigGenerate fills out the TSIG record attached to the message. // The message should contain // a "stub" TSIG RR with the algorithm, key name (owner name of the RR), // time fudge (defaults to 300 seconds) and the current time // The TSIG MAC is saved in that Tsig RR. // When TsigGenerate is called for the first time requestMAC is set to the empty string and // timersOnly is false. // If something goes wrong an error is returned, otherwise it is nil. func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) { if !m.IsTsig() { panic("TSIG not last RR in additional") } // If we barf here, the caller is to blame rawsecret, err := packBase64([]byte(secret)) if err != nil { return nil, "", err } rr := m.Extra[len(m.Extra)-1].(*RR_TSIG) m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg mbuf, ok := m.Pack() if !ok { return nil, "", ErrPack } buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly) t := new(RR_TSIG) var h hash.Hash switch rr.Algorithm { case HmacMD5: h = hmac.New(md5.New, []byte(rawsecret)) case HmacSHA1: h = hmac.New(sha1.New, []byte(rawsecret)) case HmacSHA256: h = hmac.New(sha256.New, []byte(rawsecret)) default: return nil, "", ErrKeyAlg } io.WriteString(h, string(buf)) t.MAC = hex.EncodeToString(h.Sum(nil)) t.MACSize = uint16(len(t.MAC) / 2) // Size is half! t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0} t.Fudge = rr.Fudge t.TimeSigned = rr.TimeSigned t.Algorithm = rr.Algorithm t.OrigId = m.MsgHdr.Id tbuf := make([]byte, t.Len()) if off, ok := packRR(t, tbuf, 0, nil, false); ok { tbuf = tbuf[:off] // reset to actual size used } else { return nil, "", ErrPack } mbuf = append(mbuf, tbuf...) RawSetExtraLen(mbuf, uint16(len(m.Extra)+1)) return mbuf, t.MAC, nil }
func (c *rc4hmac) Decrypt(salt []byte, algo, usage int, data []byte) ([]byte, error) { switch usage { case gssSequenceNumber: if algo != cryptGssRc4Hmac && algo != cryptGssNone { return nil, ErrProtocol } return c.Encrypt(salt, usage, data), nil case gssWrapSeal: // GSS sealing uses an external checksum for integrity and // since RC4 is symettric we can just reencrypt the data if algo != cryptGssRc4Hmac { return nil, ErrProtocol } return c.Encrypt(salt, usage, data), nil } if algo != cryptRc4Hmac || len(data) < 24 { return nil, ErrProtocol } // Hash the key and usage together to get the HMAC-MD5 key h1 := hmac.New(md5.New, c.key) binary.Write(h1, binary.LittleEndian, rc4HmacUsage(usage)) K1 := h1.Sum(nil) // Calculate the RC4 key using the checksum h3 := hmac.New(md5.New, K1) h3.Write(data[:16]) K3 := h3.Sum(nil) // Decrypt d.Data[16:] in place with 16:24 being random data and 24: // being the encrypted data r, _ := rc4.NewCipher(K3) r.XORKeyStream(data[16:], data[16:]) // Recalculate the checksum using the decrypted data ch := hmac.New(md5.New, K1) ch.Write(data[16:]) chk := ch.Sum(nil) // Check the input checksum if subtle.ConstantTimeCompare(chk, data[:16]) != 1 { return nil, ErrProtocol } return data[24:], nil }