github.com/defanghe/fabric@v2.1.1+incompatible/bccsp/sw/aes.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sw 18 19 import ( 20 "bytes" 21 "crypto/aes" 22 "crypto/cipher" 23 "crypto/rand" 24 "errors" 25 "fmt" 26 "io" 27 28 "github.com/hyperledger/fabric/bccsp" 29 ) 30 31 // GetRandomBytes returns len random looking bytes 32 func GetRandomBytes(len int) ([]byte, error) { 33 if len < 0 { 34 return nil, errors.New("Len must be larger than 0") 35 } 36 37 buffer := make([]byte, len) 38 39 n, err := rand.Read(buffer) 40 if err != nil { 41 return nil, err 42 } 43 if n != len { 44 return nil, fmt.Errorf("Buffer not filled. Requested [%d], got [%d]", len, n) 45 } 46 47 return buffer, nil 48 } 49 50 func pkcs7Padding(src []byte) []byte { 51 padding := aes.BlockSize - len(src)%aes.BlockSize 52 padtext := bytes.Repeat([]byte{byte(padding)}, padding) 53 return append(src, padtext...) 54 } 55 56 func pkcs7UnPadding(src []byte) ([]byte, error) { 57 length := len(src) 58 unpadding := int(src[length-1]) 59 60 if unpadding > aes.BlockSize || unpadding == 0 { 61 return nil, errors.New("Invalid pkcs7 padding (unpadding > aes.BlockSize || unpadding == 0)") 62 } 63 64 pad := src[len(src)-unpadding:] 65 for i := 0; i < unpadding; i++ { 66 if pad[i] != byte(unpadding) { 67 return nil, errors.New("Invalid pkcs7 padding (pad[i] != unpadding)") 68 } 69 } 70 71 return src[:(length - unpadding)], nil 72 } 73 74 func aesCBCEncrypt(key, s []byte) ([]byte, error) { 75 return aesCBCEncryptWithRand(rand.Reader, key, s) 76 } 77 78 func aesCBCEncryptWithRand(prng io.Reader, key, s []byte) ([]byte, error) { 79 if len(s)%aes.BlockSize != 0 { 80 return nil, errors.New("Invalid plaintext. It must be a multiple of the block size") 81 } 82 83 block, err := aes.NewCipher(key) 84 if err != nil { 85 return nil, err 86 } 87 88 ciphertext := make([]byte, aes.BlockSize+len(s)) 89 iv := ciphertext[:aes.BlockSize] 90 if _, err := io.ReadFull(prng, iv); err != nil { 91 return nil, err 92 } 93 94 mode := cipher.NewCBCEncrypter(block, iv) 95 mode.CryptBlocks(ciphertext[aes.BlockSize:], s) 96 97 return ciphertext, nil 98 } 99 100 func aesCBCEncryptWithIV(IV []byte, key, s []byte) ([]byte, error) { 101 if len(s)%aes.BlockSize != 0 { 102 return nil, errors.New("Invalid plaintext. It must be a multiple of the block size") 103 } 104 105 if len(IV) != aes.BlockSize { 106 return nil, errors.New("Invalid IV. It must have length the block size") 107 } 108 109 block, err := aes.NewCipher(key) 110 if err != nil { 111 return nil, err 112 } 113 114 ciphertext := make([]byte, aes.BlockSize+len(s)) 115 copy(ciphertext[:aes.BlockSize], IV) 116 117 mode := cipher.NewCBCEncrypter(block, IV) 118 mode.CryptBlocks(ciphertext[aes.BlockSize:], s) 119 120 return ciphertext, nil 121 } 122 123 func aesCBCDecrypt(key, src []byte) ([]byte, error) { 124 block, err := aes.NewCipher(key) 125 if err != nil { 126 return nil, err 127 } 128 129 if len(src) < aes.BlockSize { 130 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 131 } 132 iv := src[:aes.BlockSize] 133 src = src[aes.BlockSize:] 134 135 if len(src)%aes.BlockSize != 0 { 136 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 137 } 138 139 mode := cipher.NewCBCDecrypter(block, iv) 140 141 mode.CryptBlocks(src, src) 142 143 return src, nil 144 } 145 146 // AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding 147 func AESCBCPKCS7Encrypt(key, src []byte) ([]byte, error) { 148 // First pad 149 tmp := pkcs7Padding(src) 150 151 // Then encrypt 152 return aesCBCEncrypt(key, tmp) 153 } 154 155 // AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding using as prng the passed to the function 156 func AESCBCPKCS7EncryptWithRand(prng io.Reader, key, src []byte) ([]byte, error) { 157 // First pad 158 tmp := pkcs7Padding(src) 159 160 // Then encrypt 161 return aesCBCEncryptWithRand(prng, key, tmp) 162 } 163 164 // AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding, the IV used is the one passed to the function 165 func AESCBCPKCS7EncryptWithIV(IV []byte, key, src []byte) ([]byte, error) { 166 // First pad 167 tmp := pkcs7Padding(src) 168 169 // Then encrypt 170 return aesCBCEncryptWithIV(IV, key, tmp) 171 } 172 173 // AESCBCPKCS7Decrypt combines CBC decryption and PKCS7 unpadding 174 func AESCBCPKCS7Decrypt(key, src []byte) ([]byte, error) { 175 // First decrypt 176 pt, err := aesCBCDecrypt(key, src) 177 if err == nil { 178 return pkcs7UnPadding(pt) 179 } 180 return nil, err 181 } 182 183 type aescbcpkcs7Encryptor struct{} 184 185 func (e *aescbcpkcs7Encryptor) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) ([]byte, error) { 186 switch o := opts.(type) { 187 case *bccsp.AESCBCPKCS7ModeOpts: 188 // AES in CBC mode with PKCS7 padding 189 190 if len(o.IV) != 0 && o.PRNG != nil { 191 return nil, errors.New("Invalid options. Either IV or PRNG should be different from nil, or both nil.") 192 } 193 194 if len(o.IV) != 0 { 195 // Encrypt with the passed IV 196 return AESCBCPKCS7EncryptWithIV(o.IV, k.(*aesPrivateKey).privKey, plaintext) 197 } else if o.PRNG != nil { 198 // Encrypt with PRNG 199 return AESCBCPKCS7EncryptWithRand(o.PRNG, k.(*aesPrivateKey).privKey, plaintext) 200 } 201 // AES in CBC mode with PKCS7 padding 202 return AESCBCPKCS7Encrypt(k.(*aesPrivateKey).privKey, plaintext) 203 case bccsp.AESCBCPKCS7ModeOpts: 204 return e.Encrypt(k, plaintext, &o) 205 default: 206 return nil, fmt.Errorf("Mode not recognized [%s]", opts) 207 } 208 } 209 210 type aescbcpkcs7Decryptor struct{} 211 212 func (*aescbcpkcs7Decryptor) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) ([]byte, error) { 213 // check for mode 214 switch opts.(type) { 215 case *bccsp.AESCBCPKCS7ModeOpts, bccsp.AESCBCPKCS7ModeOpts: 216 // AES in CBC mode with PKCS7 padding 217 return AESCBCPKCS7Decrypt(k.(*aesPrivateKey).privKey, ciphertext) 218 default: 219 return nil, fmt.Errorf("Mode not recognized [%s]", opts) 220 } 221 }