@@ -133,6 +133,61 @@ static struct kpp_alg ecdh_nist_p384 = {
133133 .exit = km_ecdh_exit ,
134134};
135135
136+ /* The ecdh secret is passed in this format:
137+ * __________________________________________________________
138+ * | secret hdr | key_size | key |
139+ * | (struct kpp_secret) | (int) | (curve_len, if present) |
140+ * ----------------------------------------------------------
141+ *
142+ * - the key_size field is mandatory, but may be 0 value.
143+ * - the key is optional.
144+ *
145+ * If key_size is 0, then key pair should be generated.
146+ * */
147+ #define ECDH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + sizeof(short))
148+
149+ static int km_ecdh_decode_secret (const u8 * buf , unsigned int len ,
150+ struct ecdh * params )
151+ {
152+ struct kpp_secret secret ;
153+ const u8 * ptr = NULL ;
154+ size_t expected_len = 0 ;
155+
156+ if (unlikely (!buf || len < ECDH_KPP_SECRET_MIN_SIZE || !params )) {
157+ return - EINVAL ;
158+ }
159+
160+ /* the type of secret should be the first byte. */
161+ ptr = buf ;
162+ memcpy (& secret , ptr , sizeof (secret ));
163+ ptr += sizeof (secret );
164+ if (secret .type != CRYPTO_KPP_SECRET_TYPE_ECDH ) {
165+ return - EINVAL ;
166+ }
167+
168+ /* the key_size field will be present */
169+ memcpy (& params -> key_size , ptr , sizeof (params -> key_size ));
170+ ptr += sizeof (params -> key_size );
171+
172+ /* Calculate expected len. Verify we got expected data. */
173+ expected_len = ECDH_KPP_SECRET_MIN_SIZE + params -> key_size ;
174+
175+ if (secret .len != expected_len ) {
176+ #ifdef WOLFKM_DEBUG_ECDH
177+ pr_err ("%s: km_ecdh_decode_secret: got %d, expected %zu" ,
178+ WOLFKM_ECDH_DRIVER , secret .len , expected_len );
179+ #endif /* WOLFKM_DEBUG_ECDH */
180+ return - EINVAL ;
181+ }
182+
183+ /* Only set the key if it was provided. */
184+ if (params -> key_size ) {
185+ params -> key = (void * )ptr ;
186+ }
187+
188+ return 0 ;
189+ }
190+
136191/*
137192 * Set the secret. Kernel crypto expects secret is passed with
138193 * struct kpp_secret as header, followed by secret data as payload.
@@ -150,6 +205,7 @@ static int km_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
150205 struct ecdh params ;
151206
152207 ctx = kpp_tfm_ctx (tfm );
208+ memset (& params , 0 , sizeof (params ));
153209
154210 switch (ctx -> curve_len ) {
155211 #if defined(LINUXKM_ECC192 )
@@ -166,8 +222,7 @@ static int km_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
166222 return - EINVAL ;
167223 }
168224
169- /* use decode key helper so we observe the same format. */
170- if (crypto_ecdh_decode_key (buf , len , & params ) < 0 ) {
225+ if (km_ecdh_decode_secret (buf , len , & params ) < 0 ) {
171226 #ifdef WOLFKM_DEBUG_ECDH
172227 pr_err ("%s: ecdh_set_secret: decode secret failed: %d" ,
173228 WOLFKM_ECDH_DRIVER , params .key_size );
0 commit comments