// Copyright 2016, 2017 Thales e-Security, Inc // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. package crypto11 import ( "crypto" "crypto/dsa" "crypto/rand" _ "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" "io" "math/big" "testing" "github.com/stretchr/testify/require" ) // Use pre-cooked groups, making new ones is too slow and doesn't test // the thing we care about right now var dsaSizes = map[dsa.ParameterSizes]*dsa.Parameters{ dsa.L1024N160: dsaParameters("162901807344330501683198681796158038892896087086101563643117520955342956222658660947046551471908694917426639943346403004016664903097104319514472496004393646085043684550200397339750548531631673569299660859981509826530366281432841569092450374450801368309873677511310151482654326760484535441347619035325248971027", "1152435081592794070452857956121091711775772698753", "115452448594884027370996574512176932912212827128999848033626686707424652518655228807676153362807773892059885310384996519508710450365985083911488963280781008704774827093959271338258878644127595592794116557826253235239116215434665533711823763161327640232154970352210500147125324244313495378864886440434350445047"), dsa.L2048N224: dsaParameters("26897309010050677376706120375514893443234451462311845264107450103587616694552775798203063987684778976094649425235043381904342317828282144890959162115530648385936228003908801487852374144335466990519500032005785121648159893054617696809139702264373725369373070626941633457622971603832559810490847598977955584343798411835596790144008113895279879074659082117447812649062019962590823347376506566929271773368811020476842094620754802895105872616973988885001858825172067780326607348935255985451124288300256500395655426867070867964116873929476668281059072072214310998391443703378306986615500676546104049539495719703519940117951", "21279492449681152694989309770053968015769408476251418501127004412991", "806074083423550090996520226918161019531020530678027294640523175956127336741123734330141199877500196483993261275159586661624671147930168776905666558638413092940255649594308870768538528038043504442900678005068039885085228576696098584188275093427119292669713986799663707376358075013805220640084303178400319317901835943666702067023936970119214055180476824871264924202941665618311395109943406576227418395899047272659412653021884375802245946147395739665170684226546861490208766142484366132284564686737604148267296225461433426617875614890925967933759512314096027440880608838689527799562179981619366217116863163848643347517"), dsa.L2048N256: dsaParameters("17112618140558405746569134228451035632946851190522147937285442098259988182250197615427085779160410421439180425324757684372143777133652794766735361927034003821174405167502004454639027705200074749864396322138822913233787614500370035203936072693687262723523490964341964969759901927635271723521044671768174187470434319243240992425833709397541419254550881926245866992880605910541826307493251693926611230487275444183879966706699255763528432543168158080992127766526692139601189110012363846432577767973841827921723244473497325201586745757496510772406382623383426532181890987571204825714955203879088898058005561306135204877009", "91121968019586848097218691760416459853586419261325465835456057472782359091757", "11440584645174460641968590902479650665148631776226218292071277461507925953586967572345732823684968840767915723600616468676971247641561301128304315573382612091463182732020028761013121095491181166498021161181825176128544846296532345606186214409027298873946181476041031383608259830471735783109449938372605549135088084178714254363472647038149745329509161045818621699799741032979200140196670711384411636885603577783522623156072149396954757319730766808882432057418486340662640743658615448774457850848807133015183403659298100852797177921099769325832019636521852355306536644565775804923805884803806962749273871634832496124563"), dsa.L3072N256: dsaParameters("3292223093076756007575154742534996337119773908047183722225998562022708727169602325355570673703977126031767898507744907641046577256340035141288034004031488512406489120451045534249225732833971818604693952828746803787139641400035401666093696260981834564456248118055149793765296502054830103686831403950712801607640861048795967036349397959545638669305551590712409193326920723566244393566858414736680142461926772620503656504255924167986033103929106720448272225556256931951085963366484599500380306971899408684747849004037207957694189418415781274826562470103438926910486414615463061843381314235226091370587221926283099048619624319791834455498858310112354321475086722140598386575332287897366827250193444772749165320615259571588848174295398383162626179797293184955390849951880022388527593205033454738502281212004414696356545085156516647817931381822225669880911822774112408110220283747435924461722168415951571106537524166169188892805803", "108867360151102455324355349853282813937921700957084486520964693771814677113683", "1557152939324444301267588704765106652107942442192133066719901270619999543077285434937381472603966361780723031759112891413917740586179484242767473407407437414309703817996415200985589914186423758047030899237374015161656689079147160316057703866877939220177527975058770672610222076376028225539948249840143348317913168294956877608194868405476013052838117032232844130922725529104417156431908522534312701383683651539112438656112551665554183084212392173005974168567420494917967524105375970433753993335902159248975586830245477125927759707545151441829187496420494441219127113977851955484097152895793192460180527358969782742628457686090239586702325662876026163849101009626548110941786173048851538499449581500118606509607658612519792319018156890523385946253475322407270910172103139620247134330065127064271570620806081501157521483092036300763874199611913859815207922006817632837708771028001952742328571406294474170839325153987075519613561"), } func dsaParameters(p, q, g string) *dsa.Parameters { var params = dsa.Parameters{ P: new(big.Int), Q: new(big.Int), G: new(big.Int), } params.P.SetString(p, 10) params.Q.SetString(q, 10) params.G.SetString(g, 10) return ¶ms } // Make dsa.PrivateKey look like a Crypto.Signer type DSAPrivateKey dsa.PrivateKey func (signer *DSAPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { key := (*dsa.PrivateKey)(signer) var sig dsaSignature var err error if sig.R, sig.S, err = dsa.Sign(rand, key, digest); err != nil { return nil, err } return sig.marshalDER() } func (signer *DSAPrivateKey) Public() crypto.PublicKey { return crypto.PublicKey(&signer.PublicKey) } func TestNativeDSA(t *testing.T) { var err error for psize, params := range dsaSizes { var key = &dsa.PrivateKey{ PublicKey: dsa.PublicKey{ Parameters: *params, Y: nil, }, X: nil, } if err = dsa.GenerateKey(key, rand.Reader); err != nil { t.Errorf("crypto.dsa.GenerateKey: %v", err) return } testDsaSigning(t, (*DSAPrivateKey)(key), psize, "native") } } func TestHardDSA(t *testing.T) { skipTest(t, skipTestDSA) ctx, err := ConfigureFromFile("config") require.NoError(t, err) defer func() { err = ctx.Close() require.NoError(t, err) }() for pSize, params := range dsaSizes { id := randomBytes() label := randomBytes() key, err := ctx.GenerateDSAKeyPairWithLabel(id, label, params) require.NoError(t, err, "Failed for key size %s", parameterSizeToString(pSize)) defer func(k Signer) { _ = k.Delete() }(key) testDsaSigning(t, key, pSize, "hard1") key2, err := ctx.FindKeyPair(id, nil) require.NoError(t, err) testDsaSigning(t, key2.(*pkcs11PrivateKeyDSA), pSize, "hard2") key3, err := ctx.FindKeyPair(nil, label) require.NoError(t, err) testDsaSigning(t, key3.(crypto.Signer), pSize, "hard3") } } func parameterSizeToString(s dsa.ParameterSizes) string { switch s { case dsa.L1024N160: return "L1024N160" case dsa.L2048N224: return "L2048N224" case dsa.L2048N256: return "L2048N256" case dsa.L3072N256: return "L3072N256" default: return "unknown" } } func testDsaSigning(t *testing.T, key crypto.Signer, psize dsa.ParameterSizes, what string) { testDsaSigningWithHash(t, key, crypto.SHA1, psize, what) testDsaSigningWithHash(t, key, crypto.SHA224, psize, what) testDsaSigningWithHash(t, key, crypto.SHA256, psize, what) testDsaSigningWithHash(t, key, crypto.SHA384, psize, what) testDsaSigningWithHash(t, key, crypto.SHA512, psize, what) } func testDsaSigningWithHash(t *testing.T, key crypto.Signer, hashFunction crypto.Hash, psize dsa.ParameterSizes, what string) { plaintext := []byte("sign me with DSA") h := hashFunction.New() _, err := h.Write(plaintext) require.NoError(t, err) plaintextHash := h.Sum([]byte{}) // weird API // According to FIPS 186-3, section 4.6, the hash should be truncated to the byte-length of the subgroup // if it is longer than the subgroup length, but crypto/dsa doesn't do it automatically. subgroupSize := (dsaSizes[psize].Q.BitLen() + 7) / 8 if len(plaintextHash) > subgroupSize { plaintextHash = plaintextHash[:subgroupSize] } sigDER, err := key.Sign(rand.Reader, plaintextHash, hashFunction) require.NoError(t, err) var sig dsaSignature err = sig.unmarshalDER(sigDER) require.NoError(t, err) dsaPubkey := key.Public().(crypto.PublicKey).(*dsa.PublicKey) if !dsa.Verify(dsaPubkey, plaintextHash, sig.R, sig.S) { t.Errorf("DSA %s Verify failed (psize %d hash %v)", what, psize, hashFunction) } } func TestDsaRequiredArgs(t *testing.T) { ctx, err := ConfigureFromFile("config") require.NoError(t, err) defer func() { require.NoError(t, ctx.Close()) }() _, err = ctx.GenerateDSAKeyPair(nil, dsaSizes[dsa.L2048N224]) require.Error(t, err) val := randomBytes() _, err = ctx.GenerateDSAKeyPairWithLabel(nil, val, dsaSizes[dsa.L2048N224]) require.Error(t, err) _, err = ctx.GenerateDSAKeyPairWithLabel(val, nil, dsaSizes[dsa.L2048N224]) require.Error(t, err) }