@@ -65,11 +65,11 @@ func (c *Client) GetConf() *internal.Configuration {
6565}
6666
6767// buildPRK derives the randomized password from the OPRF output.
68- func (c * Client ) buildPRK (evaluation * ecc.Element ) []byte {
68+ func (c * Client ) buildPRK (evaluation * ecc.Element , ksfSalt , kdfSalt [] byte , ksfLength int ) []byte {
6969 output := c .OPRF .Finalize (evaluation )
70- stretched := c .conf .KSF .Harden (output , c . conf . KSFSalt , c . conf . Hash . Size () )
70+ stretched := c .conf .KSF .Harden (output , ksfSalt , ksfLength )
7171
72- return c .conf .KDF .Extract (nil , encoding .Concat (output , stretched ))
72+ return c .conf .KDF .Extract (kdfSalt , encoding .Concat (output , stretched ))
7373}
7474
7575// ClientRegistrationInitOptions enables setting internal client values for the client registration.
@@ -106,31 +106,50 @@ type ClientRegistrationFinalizeOptions struct {
106106 ServerIdentity []byte
107107 // EnvelopeNonce : optional.
108108 EnvelopeNonce []byte
109+ // KDFSalt: optional.
110+ KDFSalt []byte
111+ // KSFSalt: optional.
112+ KSFSalt []byte
113+ // KSFParameters: optional.
114+ KSFParameters []int
115+ // KSFLength: optional.
116+ KSFLength uint32
109117}
110118
111- func initClientRegistrationFinalizeOptions (options []ClientRegistrationFinalizeOptions ) * keyrecovery.Credentials {
119+ func (c * Client ) initClientRegistrationFinalizeOptions (
120+ options []ClientRegistrationFinalizeOptions ,
121+ ) (* keyrecovery.Credentials , []byte , []byte , int ) {
112122 if len (options ) == 0 {
113123 return & keyrecovery.Credentials {
114124 ClientIdentity : nil ,
115125 ServerIdentity : nil ,
116126 EnvelopeNonce : nil ,
117- }
127+ }, nil , nil , c .conf .Group .ElementLength ()
128+ }
129+
130+ if len (options [0 ].KSFParameters ) != 0 {
131+ c .conf .KSF .Parameterize (options [0 ].KSFParameters ... )
132+ }
133+
134+ ksfLength := int (options [0 ].KSFLength )
135+ if ksfLength == 0 {
136+ ksfLength = c .conf .Group .ElementLength ()
118137 }
119138
120139 return & keyrecovery.Credentials {
121140 ClientIdentity : options [0 ].ClientIdentity ,
122141 ServerIdentity : options [0 ].ServerIdentity ,
123142 EnvelopeNonce : options [0 ].EnvelopeNonce ,
124- }
143+ }, options [ 0 ]. KSFSalt , options [ 0 ]. KDFSalt , ksfLength
125144}
126145
127146// RegistrationFinalize returns a RegistrationRecord message given the identities and the server's RegistrationResponse.
128147func (c * Client ) RegistrationFinalize (
129148 resp * message.RegistrationResponse ,
130149 options ... ClientRegistrationFinalizeOptions ,
131150) (record * message.RegistrationRecord , exportKey []byte ) {
132- credentials := initClientRegistrationFinalizeOptions (options )
133- randomizedPassword := c .buildPRK (resp .EvaluatedMessage )
151+ credentials , ksfSalt , kdfSalt , ksfLength := c . initClientRegistrationFinalizeOptions (options )
152+ randomizedPassword := c .buildPRK (resp .EvaluatedMessage , ksfSalt , kdfSalt , ksfLength )
134153 maskingKey := c .conf .KDF .Expand (randomizedPassword , []byte (tag .MaskingKey ), c .conf .KDF .Size ())
135154 envelope , clientPublicKey , exportKey := keyrecovery .Store (c .conf , randomizedPassword , resp .Pks , credentials )
136155
@@ -151,20 +170,16 @@ type GenerateKE1Options struct {
151170 // AKENonce: optional.
152171 AKENonce []byte
153172 // AKENonceLength: optional, overrides the default length of the nonce to be created if no nonce is provided.
154- AKENonceLength uint
155- }
156-
157- func (c GenerateKE1Options ) get () (* ecc.Scalar , ake.Options ) {
158- return c .OPRFBlind , ake.Options {
159- KeyShareSeed : c .KeyShareSeed ,
160- Nonce : c .AKENonce ,
161- NonceLength : c .AKENonceLength ,
162- }
173+ AKENonceLength uint32
163174}
164175
165176func getGenerateKE1Options (options []GenerateKE1Options ) (* ecc.Scalar , ake.Options ) {
166177 if len (options ) != 0 {
167- return options [0 ].get ()
178+ return options [0 ].OPRFBlind , ake.Options {
179+ KeyShareSeed : options [0 ].KeyShareSeed ,
180+ Nonce : options [0 ].AKENonce ,
181+ NonceLength : options [0 ].AKENonceLength ,
182+ }
168183 }
169184
170185 return nil , ake.Options {
@@ -191,20 +206,37 @@ type GenerateKE3Options struct {
191206 ClientIdentity []byte
192207 // ServerIdentity: optional.
193208 ServerIdentity []byte
209+ // KDFSalt: optional.
210+ KDFSalt []byte
211+ // KSFSalt: optional.
212+ KSFSalt []byte
213+ // KSFParameters: optional.
214+ KSFParameters []int
215+ // KSFLength: optional.
216+ KSFLength uint32
194217}
195218
196- func initGenerateKE3Options (options []GenerateKE3Options ) * ake.Identities {
219+ func ( c * Client ) initGenerateKE3Options (options []GenerateKE3Options ) ( * ake.Identities , [] byte , [] byte , int ) {
197220 if len (options ) == 0 {
198221 return & ake.Identities {
199222 ClientIdentity : nil ,
200223 ServerIdentity : nil ,
201- }
224+ }, nil , nil , c .conf .Group .ElementLength ()
225+ }
226+
227+ if len (options [0 ].KSFParameters ) != 0 {
228+ c .conf .KSF .Parameterize (options [0 ].KSFParameters ... )
229+ }
230+
231+ ksfLength := int (options [0 ].KSFLength )
232+ if ksfLength == 0 {
233+ ksfLength = c .conf .Group .ElementLength ()
202234 }
203235
204236 return & ake.Identities {
205237 ClientIdentity : options [0 ].ClientIdentity ,
206238 ServerIdentity : options [0 ].ServerIdentity ,
207- }
239+ }, options [ 0 ]. KSFSalt , options [ 0 ]. KDFSalt , ksfLength
208240}
209241
210242// GenerateKE3 returns a KE3 message given the server's KE2 response message and the identities. If the idc
@@ -221,10 +253,10 @@ func (c *Client) GenerateKE3(
221253 return nil , nil , errInvalidMaskedLength
222254 }
223255
224- identities := initGenerateKE3Options (options )
256+ identities , ksfSalt , kdfSalt , ksfLength := c . initGenerateKE3Options (options )
225257
226258 // Finalize the OPRF.
227- randomizedPassword := c .buildPRK (ke2 .EvaluatedMessage )
259+ randomizedPassword := c .buildPRK (ke2 .EvaluatedMessage , ksfSalt , kdfSalt , ksfLength )
228260
229261 // Decrypt the masked response.
230262 serverPublicKey , serverPublicKeyBytes ,
0 commit comments