github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/p2p/crypto/secio/al.go (about) 1 package secio 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "crypto/aes" 9 "crypto/cipher" 10 "crypto/hmac" 11 "crypto/sha1" 12 "crypto/sha256" 13 "crypto/sha512" 14 "hash" 15 16 bfish "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/crypto/blowfish" 17 ci "github.com/ipfs/go-ipfs/p2p/crypto" 18 ) 19 20 // List of supported ECDH curves 21 var SupportedExchanges = "P-256,P-384,P-521" 22 23 // List of supported Ciphers 24 var SupportedCiphers = "AES-256,AES-128,Blowfish" 25 26 // List of supported Hashes 27 var SupportedHashes = "SHA256,SHA512" 28 29 type HMAC struct { 30 hash.Hash 31 size int 32 } 33 34 // encParams represent encryption parameters 35 type encParams struct { 36 // keys 37 permanentPubKey ci.PubKey 38 ephemeralPubKey []byte 39 keys ci.StretchedKeys 40 41 // selections 42 curveT string 43 cipherT string 44 hashT string 45 46 // cipher + mac 47 cipher cipher.Stream 48 mac HMAC 49 } 50 51 func (e *encParams) makeMacAndCipher() error { 52 m, err := newMac(e.hashT, e.keys.MacKey) 53 if err != nil { 54 return err 55 } 56 57 bc, err := newBlockCipher(e.cipherT, e.keys.CipherKey) 58 if err != nil { 59 return err 60 } 61 62 e.cipher = cipher.NewCTR(bc, e.keys.IV) 63 e.mac = m 64 return nil 65 } 66 67 func newMac(hashType string, key []byte) (HMAC, error) { 68 switch hashType { 69 case "SHA1": 70 return HMAC{hmac.New(sha1.New, key), sha1.Size}, nil 71 case "SHA512": 72 return HMAC{hmac.New(sha512.New, key), sha512.Size}, nil 73 case "SHA256": 74 return HMAC{hmac.New(sha256.New, key), sha256.Size}, nil 75 default: 76 return HMAC{}, fmt.Errorf("Unrecognized hash type: %s", hashType) 77 } 78 } 79 80 func newBlockCipher(cipherT string, key []byte) (cipher.Block, error) { 81 switch cipherT { 82 case "AES-128", "AES-256": 83 return aes.NewCipher(key) 84 case "Blowfish": 85 return bfish.NewCipher(key) 86 default: 87 return nil, fmt.Errorf("Unrecognized cipher type: %s", cipherT) 88 } 89 } 90 91 // Determines which algorithm to use. Note: f(a, b) = f(b, a) 92 func selectBest(order int, p1, p2 string) (string, error) { 93 var f, s []string 94 switch { 95 case order < 0: 96 f = strings.Split(p2, ",") 97 s = strings.Split(p1, ",") 98 case order > 0: 99 f = strings.Split(p1, ",") 100 s = strings.Split(p2, ",") 101 default: // Exact same preferences. 102 p := strings.Split(p1, ",") 103 return p[0], nil 104 } 105 106 for _, fc := range f { 107 for _, sc := range s { 108 if fc == sc { 109 return fc, nil 110 } 111 } 112 } 113 114 return "", errors.New("No algorithms in common!") 115 }