Skip to content

Commit 68aef4e

Browse files
committed
Removing primitives package dependency from BCCSP
This change-set removes the dependency on the initialization of the primitives package from the software-based BCCSP. This is the first step in removing dependency to the primitives package from the fabric. This change-set comes in the context of: https://jira.hyperledger.org/browse/FAB-354 Change-Id: I062162400970bb8fa54aa953161ddcac538c2159 Signed-off-by: Angelo De Caro <[email protected]>
1 parent 21a4c6a commit 68aef4e

File tree

8 files changed

+147
-37
lines changed

8 files changed

+147
-37
lines changed

core/crypto/bccsp/factory/sw_factory.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ func (f *SWFactory) Get(opts Opts) (bccsp.BCCSP, error) {
5454

5555
if !opts.Ephemeral() {
5656
f.initOnce.Do(func() {
57-
f.bccsp, f.err = sw.New()
57+
f.bccsp, f.err = sw.NewDefaultSecurityLevel()
5858
return
5959
})
6060
return f.bccsp, f.err
6161
}
6262

63-
return sw.New()
63+
return sw.NewDefaultSecurityLevel()
6464
}
6565

6666
// SwOpts contains options for the SWFactory

core/crypto/bccsp/signer/signer_test.go

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222

2323
"github.com/hyperledger/fabric/core/crypto/bccsp"
2424
"github.com/hyperledger/fabric/core/crypto/bccsp/sw"
25-
"github.com/hyperledger/fabric/core/crypto/primitives"
2625
"github.com/spf13/viper"
2726
)
2827

@@ -32,11 +31,10 @@ var (
3231

3332
func getBCCSP(t *testing.T) bccsp.BCCSP {
3433
if swBCCSPInstance == nil {
35-
primitives.InitSecurityLevel("SHA2", 256)
3634
viper.Set("security.bccsp.default.keyStorePath", os.TempDir())
3735

3836
var err error
39-
swBCCSPInstance, err = sw.New()
37+
swBCCSPInstance, err = sw.NewDefaultSecurityLevel()
4038
if err != nil {
4139
t.Fatalf("Failed initializing key store [%s]", err)
4240
}
@@ -95,12 +93,18 @@ func TestSign(t *testing.T) {
9593
}
9694

9795
msg := []byte("Hello World")
98-
signature, err := signer.Sign(rand.Reader, primitives.Hash(msg), nil)
96+
97+
digest, err := csp.Hash(msg, nil)
98+
if err != nil {
99+
t.Fatalf("Failed generating digest [%s]", err)
100+
}
101+
102+
signature, err := signer.Sign(rand.Reader, digest, nil)
99103
if err != nil {
100104
t.Fatalf("Failed generating ECDSA signature [%s]", err)
101105
}
102106

103-
valid, err := csp.Verify(k, signature, primitives.Hash(msg), nil)
107+
valid, err := csp.Verify(k, signature, digest, nil)
104108
if err != nil {
105109
t.Fatalf("Failed verifying ECDSA signature [%s]", err)
106110
}

core/crypto/bccsp/sw/aeskey.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ package sw
1818
import (
1919
"errors"
2020

21+
"crypto/sha256"
22+
2123
"github.com/hyperledger/fabric/core/crypto/bccsp"
22-
"github.com/hyperledger/fabric/core/crypto/primitives"
2324
)
2425

2526
type aesPrivateKey struct {
@@ -39,7 +40,9 @@ func (k *aesPrivateKey) Bytes() (raw []byte, err error) {
3940

4041
// SKI returns the subject key identifier of this key.
4142
func (k *aesPrivateKey) SKI() (ski []byte) {
42-
return primitives.Hash(k.k)
43+
hash := sha256.New()
44+
hash.Write(k.k)
45+
return hash.Sum(nil)
4346
}
4447

4548
// Symmetric returns true if this key is a symmetric key,

core/crypto/bccsp/sw/conf.go

+69-3
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,35 @@ import (
2121

2222
"os"
2323

24+
"crypto/elliptic"
25+
"crypto/sha256"
26+
"crypto/sha512"
27+
"fmt"
28+
"hash"
29+
2430
"github.com/spf13/viper"
31+
"golang.org/x/crypto/sha3"
2532
)
2633

2734
type config struct {
28-
keystorePath string
35+
keystorePath string
36+
securityLevel int
37+
hashFamily string
2938

3039
configurationPathProperty string
40+
ellipticCurve elliptic.Curve
41+
hashFunction func() hash.Hash
42+
aesBitLength int
43+
rsaBitLength int
3144
}
3245

33-
func (conf *config) init() error {
46+
func (conf *config) init(securityLevel int, hashFamily string) error {
47+
// Set security level
48+
err := conf.setSecurityLevel(securityLevel, hashFamily)
49+
if err != nil {
50+
return fmt.Errorf("Failed initliazing security level [%s]", err)
51+
}
52+
// Set ks path
3453
conf.configurationPathProperty = "security.bccsp.default.keyStorePath"
3554

3655
// Check mandatory fields
@@ -45,12 +64,59 @@ func (conf *config) init() error {
4564
// Set configuration path
4665
rootPath = filepath.Join(rootPath, "crypto")
4766

48-
// Set ks path
4967
conf.keystorePath = filepath.Join(rootPath, "ks")
5068

5169
return nil
5270
}
5371

72+
func (conf *config) setSecurityLevel(securityLevel int, hashFamily string) (err error) {
73+
switch hashFamily {
74+
case "SHA2":
75+
err = conf.setSecurityLevelSHA2(securityLevel)
76+
case "SHA3":
77+
err = conf.setSecurityLevelSHA3(securityLevel)
78+
default:
79+
err = fmt.Errorf("Hash Family not supported [%s]", hashFamily)
80+
}
81+
return
82+
}
83+
84+
func (conf *config) setSecurityLevelSHA2(level int) (err error) {
85+
switch level {
86+
case 256:
87+
conf.ellipticCurve = elliptic.P256()
88+
conf.hashFunction = sha256.New
89+
conf.rsaBitLength = 2048
90+
conf.aesBitLength = 32
91+
case 384:
92+
conf.ellipticCurve = elliptic.P384()
93+
conf.hashFunction = sha512.New384
94+
conf.rsaBitLength = 3072
95+
conf.aesBitLength = 32
96+
default:
97+
err = fmt.Errorf("Security level not supported [%d]", level)
98+
}
99+
return
100+
}
101+
102+
func (conf *config) setSecurityLevelSHA3(level int) (err error) {
103+
switch level {
104+
case 256:
105+
conf.ellipticCurve = elliptic.P256()
106+
conf.hashFunction = sha3.New256
107+
conf.rsaBitLength = 2048
108+
conf.aesBitLength = 32
109+
case 384:
110+
conf.ellipticCurve = elliptic.P384()
111+
conf.hashFunction = sha3.New384
112+
conf.rsaBitLength = 3072
113+
conf.aesBitLength = 32
114+
default:
115+
err = fmt.Errorf("Security level not supported [%d]", level)
116+
}
117+
return
118+
}
119+
54120
func (conf *config) checkProperty(property string) error {
55121
res := viper.GetString(property)
56122
if res == "" {

core/crypto/bccsp/sw/ecdsakey.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"crypto/x509"
2121
"fmt"
2222

23+
"crypto/sha256"
24+
2325
"github.com/hyperledger/fabric/core/crypto/bccsp"
2426
"github.com/hyperledger/fabric/core/crypto/primitives"
2527
)
@@ -44,7 +46,9 @@ func (k *ecdsaPrivateKey) SKI() (ski []byte) {
4446
raw, _ := primitives.PrivateKeyToDER(k.k)
4547
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.
4648

47-
return primitives.Hash(raw)
49+
hash := sha256.New()
50+
hash.Write(raw)
51+
return hash.Sum(nil)
4852
}
4953

5054
// Symmetric returns true if this key is a symmetric key,
@@ -89,7 +93,9 @@ func (k *ecdsaPublicKey) SKI() (ski []byte) {
8993
raw, _ := primitives.PublicKeyToPEM(k.k, nil)
9094
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.
9195

92-
return primitives.Hash(raw)
96+
hash := sha256.New()
97+
hash.Write(raw)
98+
return hash.Sum(nil)
9399
}
94100

95101
// Symmetric returns true if this key is a symmetric key,

core/crypto/bccsp/sw/impl.go

+34-15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import (
3030

3131
"crypto/x509"
3232

33+
"crypto/hmac"
34+
3335
"github.com/hyperledger/fabric/core/crypto/bccsp"
3436
"github.com/hyperledger/fabric/core/crypto/primitives"
3537
"github.com/hyperledger/fabric/core/crypto/utils"
@@ -40,10 +42,17 @@ var (
4042
logger = logging.MustGetLogger("SW_BCCSP")
4143
)
4244

43-
// New returns a new instance of the software-based BCCSP.
44-
func New() (bccsp.BCCSP, error) {
45+
// NewDefaultSecurityLevel returns a new instance of the software-based BCCSP
46+
// at security level 256 and hash family SHA2
47+
func NewDefaultSecurityLevel() (bccsp.BCCSP, error) {
48+
return New(256, "SHA2")
49+
}
50+
51+
// New returns a new instance of the software-based BCCSP
52+
// set at the passed security level and hash family.
53+
func New(securityLevel int, hashFamily string) (bccsp.BCCSP, error) {
4554
conf := &config{}
46-
err := conf.init()
55+
err := conf.init(securityLevel, hashFamily)
4756
if err != nil {
4857
return nil, fmt.Errorf("Failed initializing configuration [%s]", err)
4958
}
@@ -52,14 +61,16 @@ func New() (bccsp.BCCSP, error) {
5261
if err := ks.init(nil, conf); err != nil {
5362
return nil, fmt.Errorf("Failed initializing key store [%s]", err)
5463
}
55-
return &impl{ks}, nil
64+
return &impl{conf, ks}, nil
5665
}
5766

5867
// SoftwareBasedBCCSP is the software-based implementation of the BCCSP.
59-
// It is based on code used in the primitives package.
68+
// It uses util code in the primitives package but does not depend on the
69+
// initialization of that package.
6070
// It can be configured via viper.
6171
type impl struct {
62-
ks *keyStore
72+
conf *config
73+
ks *keyStore
6374
}
6475

6576
// KeyGen generates a key using opts.
@@ -72,7 +83,7 @@ func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
7283
// Parse algorithm
7384
switch opts.Algorithm() {
7485
case bccsp.ECDSA:
75-
lowLevelKey, err := primitives.NewECDSAKey()
86+
lowLevelKey, err := ecdsa.GenerateKey(csp.conf.ellipticCurve, rand.Reader)
7687
if err != nil {
7788
return nil, fmt.Errorf("Failed generating ECDSA key [%s]", err)
7889
}
@@ -90,7 +101,7 @@ func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
90101

91102
return k, nil
92103
case bccsp.AES:
93-
lowLevelKey, err := primitives.GenAESKey()
104+
lowLevelKey, err := primitives.GetRandomBytes(csp.conf.aesBitLength)
94105

95106
if err != nil {
96107
return nil, fmt.Errorf("Failed generating AES key [%s]", err)
@@ -109,7 +120,7 @@ func (csp *impl) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
109120

110121
return k, nil
111122
case bccsp.RSA:
112-
lowLevelKey, err := primitives.NewRSAKey()
123+
lowLevelKey, err := rsa.GenerateKey(rand.Reader, csp.conf.rsaBitLength)
113124

114125
if err != nil {
115126
return nil, fmt.Errorf("Failed generating RSA (2048) key [%s]", err)
@@ -216,7 +227,9 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e
216227
case *bccsp.HMACTruncated256AESDeriveKeyOpts:
217228
hmacOpts := opts.(*bccsp.HMACTruncated256AESDeriveKeyOpts)
218229

219-
hmacedKey := &aesPrivateKey{primitives.HMACAESTruncated(aesK.k, hmacOpts.Argument()), false}
230+
mac := hmac.New(csp.conf.hashFunction, aesK.k)
231+
mac.Write(hmacOpts.Argument())
232+
hmacedKey := &aesPrivateKey{mac.Sum(nil)[:csp.conf.aesBitLength], false}
220233

221234
// If the key is not Ephemeral, store it.
222235
if !opts.Ephemeral() {
@@ -233,7 +246,9 @@ func (csp *impl) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, e
233246

234247
hmacOpts := opts.(*bccsp.HMACDeriveKeyOpts)
235248

236-
hmacedKey := &aesPrivateKey{primitives.HMAC(aesK.k, hmacOpts.Argument()), true}
249+
mac := hmac.New(csp.conf.hashFunction, aesK.k)
250+
mac.Write(hmacOpts.Argument())
251+
hmacedKey := &aesPrivateKey{mac.Sum(nil), true}
237252

238253
// If the key is not Ephemeral, store it.
239254
if !opts.Ephemeral() {
@@ -484,12 +499,16 @@ func (csp *impl) GetKey(ski []byte) (k bccsp.Key, err error) {
484499
// Hash hashes messages msg using options opts.
485500
func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (hash []byte, err error) {
486501
if opts == nil {
487-
return primitives.Hash(msg), nil
502+
hash := csp.conf.hashFunction()
503+
hash.Write(msg)
504+
return hash.Sum(nil), nil
488505
}
489506

490507
switch opts.Algorithm() {
491508
case bccsp.DefaultHash, bccsp.SHA:
492-
return primitives.Hash(msg), nil
509+
hash := csp.conf.hashFunction()
510+
hash.Write(msg)
511+
return hash.Sum(nil), nil
493512
default:
494513
return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
495514
}
@@ -499,12 +518,12 @@ func (csp *impl) Hash(msg []byte, opts bccsp.HashOpts) (hash []byte, err error)
499518
// If opts is nil then the default hash function is returned.
500519
func (csp *impl) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) {
501520
if opts == nil {
502-
return primitives.NewHash(), nil
521+
return csp.conf.hashFunction(), nil
503522
}
504523

505524
switch opts.Algorithm() {
506525
case bccsp.SHA, bccsp.DefaultHash:
507-
return primitives.NewHash(), nil
526+
return csp.conf.hashFunction(), nil
508527
default:
509528
return nil, fmt.Errorf("Algorithm not recognized [%s]", opts.Algorithm())
510529
}

core/crypto/bccsp/sw/impl_test.go

+12-6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ import (
3131
"net"
3232
"time"
3333

34+
"crypto/ecdsa"
35+
"crypto/elliptic"
36+
"crypto/sha256"
37+
3438
"github.com/hyperledger/fabric/core/crypto/bccsp"
3539
"github.com/hyperledger/fabric/core/crypto/bccsp/signer"
3640
"github.com/hyperledger/fabric/core/crypto/primitives"
@@ -43,11 +47,10 @@ var (
4347

4448
func getBCCSP(t *testing.T) bccsp.BCCSP {
4549
if swBCCSPInstance == nil {
46-
primitives.InitSecurityLevel("SHA2", 256)
4750
viper.Set("security.bccsp.default.keyStorePath", os.TempDir())
4851

4952
var err error
50-
swBCCSPInstance, err = New()
53+
swBCCSPInstance, err = NewDefaultSecurityLevel()
5154
if err != nil {
5255
t.Fatalf("Failed initializing key store [%s]", err)
5356
}
@@ -418,8 +421,8 @@ func TestECDSAKeyImportFromECDSAPublicKey(t *testing.T) {
418421
func TestECDSAKeyImportFromECDSAPrivateKey(t *testing.T) {
419422
csp := getBCCSP(t)
420423

421-
// Generate an ECDSA key
422-
key, err := primitives.NewECDSAKey()
424+
// Generate an ECDSA key, default is P256
425+
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
423426
if err != nil {
424427
t.Fatalf("Failed generating ECDSA key [%s]", err)
425428
}
@@ -752,7 +755,7 @@ func TestHMACKeyDerivOverAES256Key(t *testing.T) {
752755
func TestAES256KeyImport(t *testing.T) {
753756
csp := getBCCSP(t)
754757

755-
raw, err := primitives.GenAESKey()
758+
raw, err := primitives.GetRandomBytes(32)
756759
if err != nil {
757760
t.Fatalf("Failed generating AES key [%s]", err)
758761
}
@@ -855,7 +858,10 @@ func TestSHA(t *testing.T) {
855858
t.Fatalf("Failed computing SHA [%s]", err)
856859
}
857860

858-
h2 := primitives.Hash(b[:])
861+
// Default HASH is SHA2 256
862+
hash := sha256.New()
863+
hash.Write(b)
864+
h2 := hash.Sum(nil)
859865

860866
if !bytes.Equal(h1, h2) {
861867
t.Fatalf("Discrempancy found in HASH result [%x], [%x]!=[%x]", b, h1, h2)

0 commit comments

Comments
 (0)