github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/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 if len(s)%aes.BlockSize != 0 { 76 return nil, errors.New("Invalid plaintext. It must be a multiple of the block size") 77 } 78 79 block, err := aes.NewCipher(key) 80 if err != nil { 81 return nil, err 82 } 83 84 ciphertext := make([]byte, aes.BlockSize+len(s)) 85 iv := ciphertext[:aes.BlockSize] 86 if _, err := io.ReadFull(rand.Reader, iv); err != nil { 87 return nil, err 88 } 89 90 mode := cipher.NewCBCEncrypter(block, iv) 91 mode.CryptBlocks(ciphertext[aes.BlockSize:], s) 92 93 return ciphertext, nil 94 } 95 96 func aesCBCDecrypt(key, src []byte) ([]byte, error) { 97 block, err := aes.NewCipher(key) 98 if err != nil { 99 return nil, err 100 } 101 102 if len(src) < aes.BlockSize { 103 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 104 } 105 iv := src[:aes.BlockSize] 106 src = src[aes.BlockSize:] 107 108 if len(src)%aes.BlockSize != 0 { 109 return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size") 110 } 111 112 mode := cipher.NewCBCDecrypter(block, iv) 113 114 mode.CryptBlocks(src, src) 115 116 return src, nil 117 } 118 119 // AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding 120 func AESCBCPKCS7Encrypt(key, src []byte) ([]byte, error) { 121 // First pad 122 tmp := pkcs7Padding(src) 123 124 // Then encrypt 125 return aesCBCEncrypt(key, tmp) 126 } 127 128 // AESCBCPKCS7Decrypt combines CBC decryption and PKCS7 unpadding 129 func AESCBCPKCS7Decrypt(key, src []byte) ([]byte, error) { 130 // First decrypt 131 pt, err := aesCBCDecrypt(key, src) 132 if err == nil { 133 return pkcs7UnPadding(pt) 134 } 135 return nil, err 136 } 137 138 type aescbcpkcs7Encryptor struct{} 139 140 func (*aescbcpkcs7Encryptor) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) (ciphertext []byte, err error) { 141 switch opts.(type) { 142 case *bccsp.AESCBCPKCS7ModeOpts, bccsp.AESCBCPKCS7ModeOpts: 143 // AES in CBC mode with PKCS7 padding 144 return AESCBCPKCS7Encrypt(k.(*aesPrivateKey).privKey, plaintext) 145 default: 146 return nil, fmt.Errorf("Mode not recognized [%s]", opts) 147 } 148 } 149 150 type aescbcpkcs7Decryptor struct{} 151 152 func (*aescbcpkcs7Decryptor) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) { 153 // check for mode 154 switch opts.(type) { 155 case *bccsp.AESCBCPKCS7ModeOpts, bccsp.AESCBCPKCS7ModeOpts: 156 // AES in CBC mode with PKCS7 padding 157 return AESCBCPKCS7Decrypt(k.(*aesPrivateKey).privKey, ciphertext) 158 default: 159 return nil, fmt.Errorf("Mode not recognized [%s]", opts) 160 } 161 }