Add PSK variants of HPKE setup functions to BoGo.

Change-Id: Ie0bef08f80aca60cfa2f94fdc4219c51d038b559
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/42684
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
chromium-5359
Daniel McArdle 5 years ago committed by CQ bot account: commit-bot@chromium.org
parent 6d2c799920
commit a673d02458
  1. 52
      ssl/test/runner/hpke/hpke.go
  2. 34
      ssl/test/runner/hpke/hpke_test.go

@ -48,6 +48,7 @@ const (
// Internal constants. // Internal constants.
const ( const (
hpkeModeBase uint8 = 0 hpkeModeBase uint8 = 0
hpkeModePSK uint8 = 1
) )
type GenerateKeyPairFunc func() (public []byte, secret []byte, e error) type GenerateKeyPairFunc func() (public []byte, secret []byte, e error)
@ -73,7 +74,7 @@ func SetupBaseSenderX25519(kdfID, aeadID uint16, publicKeyR, info []byte, ephemK
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
context, err = keySchedule(X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info) context, err = keySchedule(hpkeModeBase, X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info, nil, nil)
return return
} }
@ -84,7 +85,32 @@ func SetupBaseReceiverX25519(kdfID, aeadID uint16, enc, secretKeyR, info []byte)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return keySchedule(X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info) return keySchedule(hpkeModeBase, X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info, nil, nil)
}
// SetupPSKSenderX25519 corresponds to the spec's SetupPSKS(), but only supports
// X25519.
func SetupPSKSenderX25519(kdfID, aeadID uint16, publicKeyR, info, psk, pskID []byte, ephemKeygen GenerateKeyPairFunc) (context *Context, enc []byte, err error) {
sharedSecret, enc, err := x25519Encap(publicKeyR, ephemKeygen)
if err != nil {
return nil, nil, err
}
context, err = keySchedule(hpkeModePSK, X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info, psk, pskID)
return
}
// SetupPSKReceiverX25519 corresponds to the spec's SetupPSKR(), but only
// supports X25519.
func SetupPSKReceiverX25519(kdfID, aeadID uint16, enc, secretKeyR, info, psk, pskID []byte) (context *Context, err error) {
sharedSecret, err := x25519Decap(enc, secretKeyR)
if err != nil {
return nil, err
}
context, err = keySchedule(hpkeModePSK, X25519WithHKDFSHA256, kdfID, aeadID, sharedSecret, info, psk, pskID)
if err != nil {
return nil, err
}
return context, nil
} }
func (c *Context) Seal(additionalData, plaintext []byte) []byte { func (c *Context) Seal(additionalData, plaintext []byte) []byte {
@ -142,18 +168,32 @@ func newAEAD(aeadID uint16, key []byte) (cipher.AEAD, error) {
return nil, errors.New("unsupported AEAD") return nil, errors.New("unsupported AEAD")
} }
func keySchedule(kemID, kdfID, aeadID uint16, sharedSecret, info []byte) (*Context, error) { func keySchedule(mode uint8, kemID, kdfID, aeadID uint16, sharedSecret, info, psk, pskID []byte) (*Context, error) {
// Verify the PSK inputs.
switch mode {
case hpkeModeBase:
if len(psk) > 0 || len(pskID) > 0 {
panic("unnecessary psk inputs were provided")
}
case hpkeModePSK:
if len(psk) == 0 || len(pskID) == 0 {
panic("missing psk inputs")
}
default:
panic("unknown mode")
}
kdfHash := getKDFHash(kdfID) kdfHash := getKDFHash(kdfID)
suiteID := buildSuiteID(kemID, kdfID, aeadID) suiteID := buildSuiteID(kemID, kdfID, aeadID)
pskIDHash := labeledExtract(kdfHash, nil, suiteID, []byte("psk_id_hash"), nil) pskIDHash := labeledExtract(kdfHash, nil, suiteID, []byte("psk_id_hash"), pskID)
infoHash := labeledExtract(kdfHash, nil, suiteID, []byte("info_hash"), info) infoHash := labeledExtract(kdfHash, nil, suiteID, []byte("info_hash"), info)
keyScheduleContext := make([]byte, 0) keyScheduleContext := make([]byte, 0)
keyScheduleContext = append(keyScheduleContext, hpkeModeBase) keyScheduleContext = append(keyScheduleContext, mode)
keyScheduleContext = append(keyScheduleContext, pskIDHash...) keyScheduleContext = append(keyScheduleContext, pskIDHash...)
keyScheduleContext = append(keyScheduleContext, infoHash...) keyScheduleContext = append(keyScheduleContext, infoHash...)
pskHash := labeledExtract(kdfHash, nil, suiteID, []byte("psk_hash"), nil) pskHash := labeledExtract(kdfHash, nil, suiteID, []byte("psk_hash"), psk)
secret := labeledExtract(kdfHash, pskHash, suiteID, []byte("secret"), sharedSecret) secret := labeledExtract(kdfHash, pskHash, suiteID, []byte("secret"), sharedSecret)
key := labeledExpand(kdfHash, secret, suiteID, []byte("key"), keyScheduleContext, expectedKeyLength(aeadID)) key := labeledExpand(kdfHash, secret, suiteID, []byte("key"), keyScheduleContext, expectedKeyLength(aeadID))

@ -71,6 +71,8 @@ type HpkeTestVector struct {
KDF uint16 `json:"kdf_id"` KDF uint16 `json:"kdf_id"`
AEAD uint16 `json:"aead_id"` AEAD uint16 `json:"aead_id"`
Info HexString `json:"info"` Info HexString `json:"info"`
PSK HexString `json:"psk"`
PSKID HexString `json:"psk_id"`
SecretKeyR HexString `json:"skRm"` SecretKeyR HexString `json:"skRm"`
SecretKeyE HexString `json:"skEm"` SecretKeyE HexString `json:"skEm"`
PublicKeyR HexString `json:"pkRm"` PublicKeyR HexString `json:"pkRm"`
@ -110,14 +112,37 @@ func TestVectors(t *testing.T) {
for testNum, testVec := range testVectors { for testNum, testVec := range testVectors {
// Skip this vector if it specifies an unsupported KEM or Mode. // Skip this vector if it specifies an unsupported KEM or Mode.
if testVec.KEM != X25519WithHKDFSHA256 || if testVec.KEM != X25519WithHKDFSHA256 ||
testVec.Mode != hpkeModeBase { (testVec.Mode != hpkeModeBase && testVec.Mode != hpkeModePSK) {
numSkippedTests++ numSkippedTests++
continue continue
} }
testVec := testVec // capture the range variable testVec := testVec // capture the range variable
t.Run(fmt.Sprintf("test%d,KDF=%d,AEAD=%d", testNum, testVec.KDF, testVec.AEAD), func(t *testing.T) { t.Run(fmt.Sprintf("test%d,KDF=%d,AEAD=%d", testNum, testVec.KDF, testVec.AEAD), func(t *testing.T) {
senderContext, enc, err := SetupBaseSenderX25519(testVec.KDF, testVec.AEAD, testVec.PublicKeyR, testVec.Info, var senderContext *Context
var receiverContext *Context
var enc []byte
var err error
switch testVec.Mode {
case hpkeModeBase:
senderContext, enc, err = SetupBaseSenderX25519(testVec.KDF, testVec.AEAD, testVec.PublicKeyR, testVec.Info,
func() ([]byte, []byte, error) {
return testVec.PublicKeyE, testVec.SecretKeyE, nil
})
if err != nil {
t.Errorf("failed to set up sender: %s", err)
return
}
checkBytesEqual(t, "sender enc", enc, testVec.Enc)
receiverContext, err = SetupBaseReceiverX25519(testVec.KDF, testVec.AEAD, enc, testVec.SecretKeyR, testVec.Info)
if err != nil {
t.Errorf("failed to set up receiver: %s", err)
return
}
case hpkeModePSK:
senderContext, enc, err = SetupPSKSenderX25519(testVec.KDF, testVec.AEAD, testVec.PublicKeyR, testVec.Info, testVec.PSK, testVec.PSKID,
func() ([]byte, []byte, error) { func() ([]byte, []byte, error) {
return testVec.PublicKeyE, testVec.SecretKeyE, nil return testVec.PublicKeyE, testVec.SecretKeyE, nil
}) })
@ -127,11 +152,14 @@ func TestVectors(t *testing.T) {
} }
checkBytesEqual(t, "sender enc", enc, testVec.Enc) checkBytesEqual(t, "sender enc", enc, testVec.Enc)
receiverContext, err := SetupBaseReceiverX25519(testVec.KDF, testVec.AEAD, enc, testVec.SecretKeyR, testVec.Info) receiverContext, err = SetupPSKReceiverX25519(testVec.KDF, testVec.AEAD, enc, testVec.SecretKeyR, testVec.Info, testVec.PSK, testVec.PSKID)
if err != nil { if err != nil {
t.Errorf("failed to set up receiver: %s", err) t.Errorf("failed to set up receiver: %s", err)
return return
} }
default:
panic("unsupported mode")
}
for encryptionNum, e := range testVec.Encryptions { for encryptionNum, e := range testVec.Encryptions {
ciphertext := senderContext.Seal(e.AdditionalData, e.Plaintext) ciphertext := senderContext.Seal(e.AdditionalData, e.Plaintext)

Loading…
Cancel
Save