Skip to content

Commit

Permalink
verify DSA key sizes
Browse files Browse the repository at this point in the history
  • Loading branch information
qmuntal committed Oct 24, 2023
1 parent 1c959ea commit d92c34c
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions cng/dsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ import (
const maxGroupSize = 32

type dsaAlgorithm struct {
handle bcrypt.ALG_HANDLE
handle bcrypt.ALG_HANDLE
allowedKeyLengths bcrypt.KEY_LENGTHS_STRUCT
}

func loadDSA() (h dsaAlgorithm, err error) {
v, err := loadOrStoreAlg(bcrypt.DSA_ALGORITHM, bcrypt.ALG_NONE_FLAG, "", func(h bcrypt.ALG_HANDLE) (interface{}, error) {
return dsaAlgorithm{h}, nil
lengths, err := getKeyLengths(bcrypt.HANDLE(h))
if err != nil {
return nil, err
}
return dsaAlgorithm{h, lengths}, nil
})
if err != nil {
return dsaAlgorithm{}, err
Expand All @@ -40,6 +45,14 @@ type DSAParameters struct {
P, Q, G BigInt
}

func (p DSAParameters) keySize() uint32 {
return uint32(len(p.P))
}

func (p DSAParameters) groupSize() uint32 {
return uint32(len(p.Q))
}

// GenerateDSAParameters generates a set of DSA parameters for a key of size L bytes.
// If L is less than or equal to 1024, the parameters are generated according to FIPS 186-2.
// If L is greater than 1024, the parameters are generated according to FIPS 186-3.
Expand All @@ -49,6 +62,9 @@ func GenerateDSAParameters(L int) (params DSAParameters, X, Y BigInt, err error)
if err != nil {
return DSAParameters{}, nil, nil, err
}
if !keyIsAllowed(h.allowedKeyLengths, uint32(L)) {
return DSAParameters{}, nil, nil, errors.New("crypto/dsa: invalid key size")
}
// To generate the parameters, we need to generate a key pair and then export the public key.
// The public key contains the parameters. We then discard the key pair.
var hkey bcrypt.KEY_HANDLE
Expand Down Expand Up @@ -107,8 +123,12 @@ func GenerateKeyDSA(params DSAParameters) (*PrivateKeyDSA, error) {
if err != nil {
return nil, err
}
keySize := params.keySize()
if !keyIsAllowed(h.allowedKeyLengths, keySize*8) {
return nil, errors.New("crypto/dsa: invalid key size")
}
var hkey bcrypt.KEY_HANDLE
if err := bcrypt.GenerateKeyPair(h.handle, &hkey, uint32(len(params.P))*8, 0); err != nil {
if err := bcrypt.GenerateKeyPair(h.handle, &hkey, keySize*8, 0); err != nil {
return nil, err
}
if err := setDSAParameter(hkey, params); err != nil {
Expand All @@ -130,6 +150,10 @@ func NewPrivateKeyDSA(params DSAParameters, X, Y BigInt) (*PrivateKeyDSA, error)
if err != nil {
return nil, err
}
keySize := params.keySize()
if !keyIsAllowed(h.allowedKeyLengths, keySize*8) {
return nil, errors.New("crypto/dsa: invalid key size")
}
hkey, err := encodeDSAKey(h.handle, params, X, Y)
if err != nil {
return nil, err
Expand All @@ -145,6 +169,10 @@ func NewPublicKeyDSA(params DSAParameters, Y BigInt) (*PublicKeyDSA, error) {
if err != nil {
return nil, err
}
keySize := params.keySize()
if !keyIsAllowed(h.allowedKeyLengths, keySize*8) {
return nil, errors.New("crypto/dsa: invalid key size")
}
hkey, err := encodeDSAKey(h.handle, params, nil, Y)
if err != nil {
return nil, err
Expand Down Expand Up @@ -212,8 +240,8 @@ func VerifyDSA(pub *PublicKeyDSA, hashed []byte, r, s BigInt) bool {
}

func encodeDSAKey(h bcrypt.ALG_HANDLE, params DSAParameters, X, Y BigInt) (bcrypt.KEY_HANDLE, error) {
keySize := uint32(len(params.P))
groupSize := uint32(len(params.Q))
keySize := params.keySize()
groupSize := params.groupSize()
private := X != nil
var blob []byte
var idx int
Expand Down Expand Up @@ -355,8 +383,8 @@ func decodeDSAKey(hkey bcrypt.KEY_HANDLE, private bool) (params DSAParameters, X

// setDSAParameter sets the DSA parameters for the given key.
func setDSAParameter(hkey bcrypt.KEY_HANDLE, params DSAParameters) error {
keySize := uint32(len(params.P))
groupSize := uint32(len(params.Q))
keySize := params.keySize()
groupSize := params.groupSize()
var blob []byte
var idx int
appendBigInt := func(b BigInt) {
Expand Down Expand Up @@ -410,7 +438,7 @@ func dsaAdjustHashSize(hkey bcrypt.KEY_HANDLE, hashed []byte, buf []byte) ([]byt
if err != nil {
return nil, err
}
groupSize := len(params.Q)
groupSize := int(params.groupSize())
if groupSize > len(buf) {
panic("output buffer too small")
}
Expand Down

0 comments on commit d92c34c

Please sign in to comment.