55 "crypto/aes"
66 "crypto/cipher"
77 "crypto/sha256"
8+ "encoding/binary"
89
910 "github.com/libp2p/go-libp2p/core/peer"
1011 "github.com/multiformats/go-multihash"
@@ -13,30 +14,39 @@ import (
1314const (
1415 // nonceLen defines length of the nonce to use for AESGCM encryption
1516 nonceLen = 12
16- // keysize defines the size of multihash key
17- keysize = 32
17+ )
18+
19+ var (
20+ // secondHashPrefix is a prefix that a mulithash is prepended with when calculating a second hash
21+ secondHashPrefix = []byte ("CR_DOUBLEHASH\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " )
22+ // deriveKeyPrefix is a prefix that a multihash is prepended with when deriving an encryption key
23+ deriveKeyPrefix = []byte ("CR_ENCRYPTIONKEY\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " )
24+ // noncePrefix is a prefix that a multihash is prepended with when calculating a nonce
25+ noncePrefix = []byte ("CR_NONCE\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " )
1826)
1927
2028// SecondSHA returns SHA256 over the payload
2129func SHA256 (payload , dest []byte ) []byte {
30+ return sha256Multiple (dest , payload )
31+ }
32+
33+ func sha256Multiple (dest []byte , payloads ... []byte ) []byte {
2234 h := sha256 .New ()
23- h .Write (payload )
35+ for _ , payload := range payloads {
36+ h .Write (payload )
37+ }
2438 return h .Sum (dest )
2539}
2640
2741// SecondMultihash calculates SHA256 over the multihash and wraps it into another multihash with DBL_SHA256 codec
2842func SecondMultihash (mh multihash.Multihash ) (multihash.Multihash , error ) {
29- prefix := []byte ("CR_DOUBLEHASH" )
30- mh , err := multihash .Sum (append (prefix , mh ... ), multihash .DBL_SHA2_256 , keysize )
31- if err != nil {
32- return nil , err
33- }
34- return mh , nil
43+ digest := SHA256 (append (secondHashPrefix , mh ... ), nil )
44+ return multihash .Encode (digest , multihash .DBL_SHA2_256 )
3545}
3646
3747// deriveKey derives encryptioin key from the passphrase using SHA256
3848func deriveKey (passphrase []byte ) []byte {
39- return SHA256 (append ([] byte ( "AESGCM" ) , passphrase ... ), nil )
49+ return SHA256 (append (deriveKeyPrefix , passphrase ... ), nil )
4050}
4151
4252// DecryptAES decrypts AES payload using the nonce and the passphrase
@@ -62,9 +72,11 @@ func EncryptAES(payload, passphrase []byte) ([]byte, []byte, error) {
6272 derivedKey := deriveKey ([]byte (passphrase ))
6373
6474 // Create initialization vector (nonse) to be used during encryption
65- // Nonce is derived from the mulithash (passpharase) so that encrypted payloads
66- // for the same multihash can be compared to each other without having to decrypt
67- nonce := SHA256 (passphrase , nil )[:nonceLen ]
75+ // Nonce is derived from the passphrase concatenated with the payload so that the encrypted payloads
76+ // for the same multihash can be compared to each other without having to decrypt them, as it's not possible.
77+ payloadLen := make ([]byte , 8 )
78+ binary .LittleEndian .PutUint64 (payloadLen , uint64 (len (payload )))
79+ nonce := sha256Multiple (nil , noncePrefix , payloadLen , payload , passphrase )[:nonceLen ]
6880
6981 // Create cypher and seal the data
7082 block , err := aes .NewCipher (derivedKey )
@@ -83,13 +95,13 @@ func EncryptAES(payload, passphrase []byte) ([]byte, []byte, error) {
8395}
8496
8597// DecryptValueKey decrypts the value key using the passphrase
86- func DecryptValueKey (valKey , passphrase [] byte ) ([]byte , error ) {
87- return DecryptAES (valKey [:nonceLen ], valKey [nonceLen :], passphrase )
98+ func DecryptValueKey (valKey , mh multihash. Multihash ) ([]byte , error ) {
99+ return DecryptAES (valKey [:nonceLen ], valKey [nonceLen :], mh )
88100}
89101
90102// EncryptValueKey encrypts raw value key using the passpharse
91- func EncryptValueKey (valKey , passphrase [] byte ) ([]byte , error ) {
92- nonce , encValKey , err := EncryptAES (valKey , passphrase )
103+ func EncryptValueKey (valKey , mh multihash. Multihash ) ([]byte , error ) {
104+ nonce , encValKey , err := EncryptAES (valKey , mh )
93105 if err != nil {
94106 return nil , err
95107 }
@@ -98,13 +110,13 @@ func EncryptValueKey(valKey, passphrase []byte) ([]byte, error) {
98110}
99111
100112// DecryptMetadata decrypts metdata using the provided passphrase
101- func DecryptMetadata (encMetadata , passphrase []byte ) ([]byte , error ) {
102- return DecryptAES (encMetadata [:nonceLen ], encMetadata [nonceLen :], passphrase )
113+ func DecryptMetadata (encMetadata , valueKey []byte ) ([]byte , error ) {
114+ return DecryptAES (encMetadata [:nonceLen ], encMetadata [nonceLen :], valueKey )
103115}
104116
105117// EncryptMetadata encrypts metadata using the provided passphrase
106- func EncryptMetadata (metadata , passphrase []byte ) ([]byte , error ) {
107- nonce , encValKey , err := EncryptAES (metadata , passphrase )
118+ func EncryptMetadata (metadata , valueKey []byte ) ([]byte , error ) {
119+ nonce , encValKey , err := EncryptAES (metadata , valueKey )
108120 if err != nil {
109121 return nil , err
110122 }
0 commit comments