github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/aeskey.go (about) 1 /* 2 Copyright (C) BABEC. All rights reserved. 3 Copyright (C) THL A29 Limited, a Tencent company. All rights reserved. 4 5 SPDX-License-Identifier: Apache-2.0 6 */ 7 8 package pkcs11 9 10 import ( 11 "crypto/rand" 12 "fmt" 13 "strconv" 14 15 "chainmaker.org/chainmaker/common/v2/crypto/hsm" 16 17 "chainmaker.org/chainmaker/common/v2/crypto/sym/util" 18 19 "github.com/pkg/errors" 20 21 "chainmaker.org/chainmaker/common/v2/crypto/sym/modes" 22 23 bccrypto "chainmaker.org/chainmaker/common/v2/crypto" 24 "github.com/miekg/pkcs11" 25 ) 26 27 var defaultAESOpts = &bccrypto.EncOpts{ 28 EncodingType: modes.PADDING_PKCS5, 29 BlockMode: modes.BLOCK_MODE_CBC, 30 EnableMAC: true, 31 Hash: 0, 32 Label: nil, 33 EnableASN1: true, 34 } 35 36 var _ bccrypto.SymmetricKey = (*aesKey)(nil) 37 38 type aesKey struct { 39 p11Ctx *P11Handle 40 keyId []byte 41 keyType P11KeyType 42 keyObject pkcs11.ObjectHandle 43 keySize int 44 blockSize int 45 } 46 47 func NewAESKey(ctx *P11Handle, keyId []byte) (bccrypto.SymmetricKey, error) { 48 //find private key 49 id, err := strconv.Atoi(string(keyId)) 50 if err != nil { 51 return nil, err 52 } 53 keyIdStr, err := hsm.GetHSMAdapter("").PKCS11_GetAESKeyId(id) 54 if err != nil { 55 return nil, err 56 } 57 58 obj, err := ctx.findSecretKey([]byte(keyIdStr)) 59 if err != nil { 60 return nil, errors.WithMessagef(err, "PKCS11 error: fail to find aes key, keyId = %s", keyIdStr) 61 } 62 63 sk := aesKey{p11Ctx: ctx, 64 keyId: keyId, 65 keyObject: *obj, 66 keyType: AES, 67 blockSize: 16, 68 } 69 70 sk.keySize, err = ctx.getSecretKeySize(*obj) 71 if err != nil { 72 return nil, errors.WithMessage(err, "failed to get aes keySize") 73 } 74 return &sk, nil 75 } 76 77 func (s *aesKey) Bytes() ([]byte, error) { 78 return s.keyId, nil 79 } 80 81 func (s *aesKey) Type() bccrypto.KeyType { 82 return bccrypto.AES 83 } 84 85 func (s *aesKey) String() (string, error) { 86 return string(s.keyId), nil 87 } 88 89 func (s *aesKey) Encrypt(plain []byte) ([]byte, error) { 90 return s.EncryptWithOpts(plain, defaultAESOpts) 91 } 92 93 func (s *aesKey) EncryptWithOpts(plain []byte, opts *bccrypto.EncOpts) ([]byte, error) { 94 iv := make([]byte, s.blockSize) 95 if _, err := rand.Read(iv); err != nil { 96 return nil, err 97 } 98 var cipherWithPad []byte 99 switch opts.BlockMode { 100 case modes.BLOCK_MODE_CBC: 101 switch opts.EncodingType { 102 case modes.PADDING_PKCS5: 103 plainWithPad := util.PKCS5Padding(plain, s.blockSize) 104 ciphertex, err := s.p11Ctx.Encrypt(s.keyObject, pkcs11.NewMechanism(pkcs11.CKM_AES_CBC, iv), plainWithPad) 105 if err != nil { 106 return nil, err 107 } 108 cipherWithPad = append(iv, ciphertex...) 109 default: 110 return nil, fmt.Errorf("sm4 CBC encryption fails: invalid padding scheme [%s]", opts.EncodingType) 111 } 112 default: 113 return nil, fmt.Errorf("sm4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 114 } 115 116 return cipherWithPad, nil 117 } 118 119 func (s *aesKey) Decrypt(ciphertext []byte) ([]byte, error) { 120 return s.DecryptWithOpts(ciphertext, defaultAESOpts) 121 } 122 123 func (s *aesKey) DecryptWithOpts(ciphertext []byte, opts *bccrypto.EncOpts) ([]byte, error) { 124 if len(ciphertext) < s.blockSize { 125 return nil, errors.New("invalid ciphertext length") 126 } 127 var plain []byte 128 switch opts.BlockMode { 129 case modes.BLOCK_MODE_CBC: 130 switch opts.EncodingType { 131 case modes.PADDING_PKCS5: 132 iv := ciphertext[:s.blockSize] 133 out, err := s.p11Ctx.Decrypt(s.keyObject, pkcs11.NewMechanism(pkcs11.CKM_AES_CBC, iv), ciphertext[s.blockSize:]) 134 if err != nil { 135 return nil, fmt.Errorf("PKCS11 error: fail to encrypt [%s]", err) 136 } 137 plain, err = util.PKCS5UnPadding(out) 138 if err != nil { 139 return nil, err 140 } 141 default: 142 return nil, fmt.Errorf("sm4 CBC encryption fails: invalid padding scheme [%s]", opts.EncodingType) 143 } 144 default: 145 return nil, fmt.Errorf("sm4 encryption fails: unknown cipher block mode [%s]", opts.BlockMode) 146 } 147 148 return plain, nil 149 }