Longer default PKCS keys
[silc.git] / lib / silcske / silcske.c
1 /*
2
3   silcske.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2014 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "silc.h"
22 #include "silcske.h"
23 #include "groups_internal.h"
24
25 /************************** Types and definitions ***************************/
26
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29   SilcSKEVerifyCb verify_key;
30   SilcSKECompletionCb completed;
31   void *context;
32 };
33
34 /************************ Static utility functions **************************/
35
36 /* States */
37 SILC_FSM_STATE(silc_ske_st_initiator_start);
38 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
39 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
40 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
41 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
42 SILC_FSM_STATE(silc_ske_st_initiator_end);
43 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
44 SILC_FSM_STATE(silc_ske_st_initiator_error);
45 SILC_FSM_STATE(silc_ske_st_initiator_failure);
46 SILC_FSM_STATE(silc_ske_st_responder_start);
47 SILC_FSM_STATE(silc_ske_st_responder_phase1);
48 SILC_FSM_STATE(silc_ske_st_responder_phase2);
49 SILC_FSM_STATE(silc_ske_st_responder_phase4);
50 SILC_FSM_STATE(silc_ske_st_responder_phase5);
51 SILC_FSM_STATE(silc_ske_st_responder_end);
52 SILC_FSM_STATE(silc_ske_st_responder_aborted);
53 SILC_FSM_STATE(silc_ske_st_responder_failure);
54 SILC_FSM_STATE(silc_ske_st_responder_error);
55 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
56 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done);
57 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end);
58 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait);
59 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
60 SILC_FSM_STATE(silc_ske_st_rekey_responder_done);
61 SILC_FSM_STATE(silc_ske_st_rekey_responder_end);
62 SILC_TASK_CALLBACK(silc_ske_packet_send_retry);
63
64 SilcSKEKeyMaterial
65 silc_ske_process_key_material(SilcSKE ske,
66                               SilcUInt32 req_iv_len,
67                               SilcUInt32 req_enc_key_len,
68                               SilcUInt32 req_hmac_key_len,
69                               SilcSKERekeyMaterial *rekey);
70 static SilcBool silc_ske_packet_send(SilcSKE ske,
71                                      SilcPacketType type,
72                                      SilcPacketFlags flags,
73                                      const unsigned char *data,
74                                      SilcUInt32 data_len);
75
76 /*
77  * Notify the owner of the ske that we failed.  Ensures that we don't make the
78  * same callout twice, as the notification callback routines are not designed
79  * to handle that case.
80  */
81 static void silc_ske_notify_failure(SilcSKE ske)
82 {
83   SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %d)",
84                   ske, ske->failure_notified));
85
86   /*
87    * First, check if we have already made a failure callout.  If so, then we
88    * will stop here.
89    */
90   if (ske->failure_notified)
91     return;
92
93   /*
94    * Mark ourselves as having already sent the failure notification here and
95    * now.
96    */
97   ske->failure_notified = TRUE;
98
99   SILC_LOG_DEBUG(("Deliver failure notification for SKE %p (%s)",
100                   ske, ske->responder ? "responder" : "initiator"));
101
102   /*
103    * Finally, make the call to the owner's registered failure callback.
104    */
105   if (ske->responder)
106     silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
107   else
108     silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
109 }
110
111 /* Packet callback */
112
113 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
114                                         SilcPacketStream stream,
115                                         SilcPacket packet,
116                                         void *callback_context,
117                                         void *app_context)
118 {
119   SilcSKE ske = callback_context;
120
121   /* Clear retransmission */
122   ske->retry_timer = SILC_SKE_RETRY_MIN;
123   ske->retry_count = 0;
124   silc_schedule_task_del_by_callback(ske->schedule,
125                                      silc_ske_packet_send_retry);
126
127   /* Signal for new packet */
128   ske->packet = packet;
129
130   /* Check if we were aborted */
131   if (ske->aborted) {
132     silc_packet_free(packet);
133     ske->packet = NULL;
134
135     if (ske->responder)
136       silc_fsm_next(&ske->fsm, silc_ske_st_responder_aborted);
137     else
138       silc_fsm_next(&ske->fsm, silc_ske_st_initiator_aborted);
139
140     silc_fsm_continue_sync(&ske->fsm);
141     return TRUE;
142   }
143
144   /* See if received failure from remote */
145   if (packet->type == SILC_PACKET_FAILURE)
146     silc_ske_notify_failure(ske);
147
148   /* Handle rekey and SUCCESS packets synchronously.  After SUCCESS packets
149      they keys are taken into use immediately, hence the synchronous
150      processing to get the keys in use as soon as possible. */
151   if (ske->rekeying || packet->type == SILC_PACKET_SUCCESS)
152     silc_fsm_continue_sync(&ske->fsm);
153   else
154     silc_fsm_continue(&ske->fsm);
155
156   return TRUE;
157 }
158
159 /* Packet stream callbacks */
160 static SilcPacketCallbacks silc_ske_stream_cbs =
161 {
162   silc_ske_packet_receive, NULL, NULL
163 };
164
165 /* Aborts SKE protocol */
166
167 static void silc_ske_abort(SilcAsyncOperation op, void *context)
168 {
169   SilcSKE ske = context;
170   ske->aborted = TRUE;
171 }
172
173 /* Public key verification completion callback */
174
175 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
176                                  void *completion_context)
177 {
178   ske->status = status;
179   SILC_FSM_CALL_CONTINUE(&ske->fsm);
180 }
181
182 /* SKR find callback */
183
184 static void silc_ske_skr_callback(SilcSKR repository,
185                                   SilcSKRFind find,
186                                   SilcSKRStatus status,
187                                   SilcDList keys, void *context)
188 {
189   SilcSKE ske = context;
190
191   silc_skr_find_free(find);
192
193   if (status != SILC_SKR_OK) {
194     if (ske->callbacks->verify_key) {
195       /* Verify from application */
196       ske->callbacks->verify_key(ske, ske->prop->public_key,
197                                  ske->callbacks->context,
198                                  silc_ske_pk_verified, NULL);
199       return;
200     }
201   }
202
203   if (keys)
204     silc_dlist_uninit(keys);
205
206   /* Continue */
207   ske->status = (status == SILC_SKR_OK ? SILC_SKE_STATUS_OK :
208                  SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY);
209   SILC_FSM_CALL_CONTINUE(&ske->fsm);
210 }
211
212 /* Checks remote and local versions */
213
214 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
215 {
216   if (!ske->remote_version || !ske->version)
217     return SILC_SKE_STATUS_BAD_VERSION;
218
219   if (!silc_parse_version_string(ske->remote_version, NULL, NULL,
220                                  NULL, NULL, NULL))
221     return SILC_SKE_STATUS_BAD_VERSION;
222
223   return SILC_SKE_STATUS_OK;
224 }
225
226 /* Selects the supported security properties from the initiator's Key
227    Exchange Start Payload.  A responder function.  Saves our reply
228    start payload to ske->start_payload. */
229
230 static SilcSKEStatus
231 silc_ske_select_security_properties(SilcSKE ske,
232                                     SilcSKEStartPayload remote_payload,
233                                     SilcSKESecurityProperties *prop)
234 {
235   SilcSKEStatus status;
236   SilcSKEStartPayload rp, payload;
237   char *cp;
238   int len;
239
240   SILC_LOG_DEBUG(("Parsing KE Start Payload"));
241
242   rp = remote_payload;
243   if (!rp)
244     return SILC_SKE_STATUS_BAD_VERSION;
245
246   /* Check for mandatory fields */
247   if (!rp->ke_grp_len) {
248     SILC_LOG_DEBUG(("KE group not defined in payload"));
249     return SILC_SKE_STATUS_BAD_PAYLOAD;
250   }
251   if (!rp->pkcs_alg_len) {
252     SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
253     return SILC_SKE_STATUS_BAD_PAYLOAD;
254   }
255   if (!rp->enc_alg_len) {
256     SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
257     return SILC_SKE_STATUS_BAD_PAYLOAD;
258   }
259   if (!rp->hash_alg_len) {
260     SILC_LOG_DEBUG(("Hash alg not defined in payload"));
261     return SILC_SKE_STATUS_BAD_PAYLOAD;
262   }
263   if (!rp->hmac_alg_len) {
264     SILC_LOG_DEBUG(("HMAC not defined in payload"));
265     return SILC_SKE_STATUS_BAD_PAYLOAD;
266   }
267
268   /* Allocate security properties */
269   *prop = silc_calloc(1, sizeof(**prop));
270   if (!(*prop))
271     return SILC_SKE_STATUS_OUT_OF_MEMORY;
272
273   /* Allocate our reply start payload */
274   payload = silc_calloc(1, sizeof(*payload));
275   if (!payload) {
276     silc_free(*prop);
277     return SILC_SKE_STATUS_OUT_OF_MEMORY;
278   }
279
280   /* Check version string */
281   ske->remote_version = silc_memdup(rp->version, rp->version_len);
282   status = silc_ske_check_version(ske);
283   if (status != SILC_SKE_STATUS_OK) {
284     ske->status = status;
285     return status;
286   }
287
288   /* Flags are returned unchanged. */
289   (*prop)->flags = payload->flags = rp->flags;
290
291   /* Take cookie, we must return it to sender unmodified. */
292   payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
293   if (!payload->cookie) {
294     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
295     return status;
296   }
297   payload->cookie_len = SILC_SKE_COOKIE_LEN;
298   memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
299
300   /* In case IV included flag and session port is set the first 16-bits of
301      cookie will include our session port. */
302   if (rp->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
303     /* Take remote port */
304     SILC_GET16_MSB((*prop)->remote_port, payload->cookie);
305
306     /* Put out port */
307     SILC_PUT16_MSB(ske->session_port, payload->cookie);
308   }
309
310   /* Put our version to our reply */
311   payload->version = strdup(ske->version);
312   if (!payload->version) {
313     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
314     return status;
315   }
316   payload->version_len = strlen(ske->version);
317
318   /* Get supported Key Exchange groups */
319   cp = rp->ke_grp_list;
320   if (cp && strchr(cp, ',')) {
321     while(cp) {
322       char *item;
323
324       len = strcspn(cp, ",");
325       item = silc_calloc(len + 1, sizeof(char));
326       if (!item) {
327         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
328         return status;
329       }
330       memcpy(item, cp, len);
331
332       SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
333
334       if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
335         SILC_LOG_DEBUG(("Found KE group `%s'", item));
336
337         payload->ke_grp_len = len;
338         payload->ke_grp_list = item;
339         break;
340       }
341
342       cp += len;
343       if (strlen(cp) == 0)
344         cp = NULL;
345       else
346         cp++;
347
348       if (item)
349         silc_free(item);
350     }
351
352     if (!payload->ke_grp_len && !payload->ke_grp_list) {
353       SILC_LOG_DEBUG(("Could not find supported KE group"));
354       silc_free(payload);
355       return SILC_SKE_STATUS_UNKNOWN_GROUP;
356     }
357   } else {
358     SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
359     SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
360
361     payload->ke_grp_len = rp->ke_grp_len;
362     payload->ke_grp_list = strdup(rp->ke_grp_list);
363   }
364
365   /* Save group to security properties */
366   status = silc_ske_group_get_by_name(payload->ke_grp_list, &(*prop)->group);
367   if (status != SILC_SKE_STATUS_OK) {
368     silc_free(payload);
369     return SILC_SKE_STATUS_UNKNOWN_GROUP;
370   }
371
372   /* Get supported PKCS algorithms */
373   cp = rp->pkcs_alg_list;
374   if (cp && strchr(cp, ',')) {
375     while(cp) {
376       char *item;
377
378       len = strcspn(cp, ",");
379       item = silc_calloc(len + 1, sizeof(char));
380       if (!item) {
381         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
382         return status;
383       }
384       memcpy(item, cp, len);
385
386       SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
387
388       if (silc_pkcs_find_algorithm(item, NULL)) {
389         SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
390
391         payload->pkcs_alg_len = len;
392         payload->pkcs_alg_list = item;
393         break;
394       }
395
396       cp += len;
397       if (strlen(cp) == 0)
398         cp = NULL;
399       else
400         cp++;
401
402       if (item)
403         silc_free(item);
404     }
405
406     if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
407       SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
408       silc_free(payload->ke_grp_list);
409       silc_free(payload);
410       return SILC_SKE_STATUS_UNKNOWN_PKCS;
411     }
412   } else {
413     SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
414     SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
415
416     payload->pkcs_alg_len = rp->pkcs_alg_len;
417     payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
418   }
419
420   /* Get supported encryption algorithms */
421   cp = rp->enc_alg_list;
422   if (cp && strchr(cp, ',')) {
423     while(cp) {
424       char *item;
425
426       len = strcspn(cp, ",");
427       item = silc_calloc(len + 1, sizeof(char));
428       if (!item) {
429         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
430         return status;
431       }
432       memcpy(item, cp, len);
433
434       SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
435
436       if (silc_cipher_is_supported(item) == TRUE) {
437         SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
438
439         payload->enc_alg_len = len;
440         payload->enc_alg_list = item;
441         break;
442       }
443
444       cp += len;
445       if (strlen(cp) == 0)
446         cp = NULL;
447       else
448         cp++;
449
450       if (item)
451         silc_free(item);
452     }
453
454     if (!payload->enc_alg_len && !payload->enc_alg_list) {
455       SILC_LOG_DEBUG(("Could not find supported encryption alg"));
456       silc_free(payload->ke_grp_list);
457       silc_free(payload->pkcs_alg_list);
458       silc_free(payload);
459       return SILC_SKE_STATUS_UNKNOWN_CIPHER;
460     }
461   } else {
462     SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
463                     rp->enc_alg_list));
464
465     payload->enc_alg_len = rp->enc_alg_len;
466     payload->enc_alg_list = strdup(rp->enc_alg_list);
467   }
468
469   /* Save selected cipher to security properties */
470   if (silc_cipher_alloc(payload->enc_alg_list, &(*prop)->cipher) == FALSE) {
471     silc_free(payload->ke_grp_list);
472     silc_free(payload->pkcs_alg_list);
473     silc_free(payload);
474     return SILC_SKE_STATUS_UNKNOWN_CIPHER;
475   }
476
477   /* Get supported hash algorithms */
478   cp = rp->hash_alg_list;
479   if (cp && strchr(cp, ',')) {
480     while(cp) {
481       char *item;
482
483       len = strcspn(cp, ",");
484       item = silc_calloc(len + 1, sizeof(char));
485       if (!item) {
486         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
487         return status;
488       }
489       memcpy(item, cp, len);
490
491       SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
492
493       if (silc_hash_is_supported(item) == TRUE) {
494         SILC_LOG_DEBUG(("Found hash alg `%s'", item));
495
496         payload->hash_alg_len = len;
497         payload->hash_alg_list = item;
498         break;
499       }
500
501       cp += len;
502       if (strlen(cp) == 0)
503         cp = NULL;
504       else
505         cp++;
506
507       if (item)
508         silc_free(item);
509     }
510
511     if (!payload->hash_alg_len && !payload->hash_alg_list) {
512       SILC_LOG_DEBUG(("Could not find supported hash alg"));
513       silc_free(payload->ke_grp_list);
514       silc_free(payload->pkcs_alg_list);
515       silc_free(payload->enc_alg_list);
516       silc_free(payload);
517       return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
518     }
519   } else {
520     SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
521                     rp->hash_alg_list));
522
523     payload->hash_alg_len = rp->hash_alg_len;
524     payload->hash_alg_list = strdup(rp->hash_alg_list);
525   }
526
527   /* Save selected hash algorithm to security properties */
528   if (silc_hash_alloc(payload->hash_alg_list, &(*prop)->hash) == FALSE) {
529     silc_free(payload->ke_grp_list);
530     silc_free(payload->pkcs_alg_list);
531     silc_free(payload->enc_alg_list);
532     silc_free(payload);
533     return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
534   }
535
536   /* Get supported HMACs */
537   cp = rp->hmac_alg_list;
538   if (cp && strchr(cp, ',')) {
539     while(cp) {
540       char *item;
541
542       len = strcspn(cp, ",");
543       item = silc_calloc(len + 1, sizeof(char));
544       if (!item) {
545         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
546         return status;
547       }
548       memcpy(item, cp, len);
549
550       SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
551
552       if (silc_hmac_is_supported(item) == TRUE) {
553         SILC_LOG_DEBUG(("Found HMAC `%s'", item));
554
555         payload->hmac_alg_len = len;
556         payload->hmac_alg_list = item;
557         break;
558       }
559
560       cp += len;
561       if (strlen(cp) == 0)
562         cp = NULL;
563       else
564         cp++;
565
566       if (item)
567         silc_free(item);
568     }
569
570     if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
571       SILC_LOG_DEBUG(("Could not find supported HMAC"));
572       silc_free(payload->ke_grp_list);
573       silc_free(payload->pkcs_alg_list);
574       silc_free(payload->enc_alg_list);
575       silc_free(payload->hash_alg_list);
576       silc_free(payload);
577       return SILC_SKE_STATUS_UNKNOWN_HMAC;
578     }
579   } else {
580     SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
581                     rp->hmac_alg_list));
582
583     payload->hmac_alg_len = rp->hmac_alg_len;
584     payload->hmac_alg_list = strdup(rp->hmac_alg_list);
585   }
586
587   /* Save selected HMACc to security properties */
588   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &(*prop)->hmac) == FALSE) {
589     silc_free(payload->ke_grp_list);
590     silc_free(payload->pkcs_alg_list);
591     silc_free(payload->enc_alg_list);
592     silc_free(payload->hash_alg_list);
593     silc_free(payload);
594     return SILC_SKE_STATUS_UNKNOWN_HMAC;
595   }
596
597   /* Get supported compression algorithms */
598   cp = rp->comp_alg_list;
599   if (cp && strchr(cp, ',')) {
600     while(cp) {
601       char *item;
602
603       len = strcspn(cp, ",");
604       item = silc_calloc(len + 1, sizeof(char));
605       if (!item) {
606         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
607         return status;
608       }
609       memcpy(item, cp, len);
610
611       SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
612
613 #if 1
614       if (!strcmp(item, "none")) {
615         SILC_LOG_DEBUG(("Found Compression `%s'", item));
616         payload->comp_alg_len = len;
617         payload->comp_alg_list = item;
618         break;
619       }
620 #else
621       if (silc_hmac_is_supported(item) == TRUE) {
622         SILC_LOG_DEBUG(("Found Compression `%s'", item));
623         payload->comp_alg_len = len;
624         payload->comp_alg_list = item;
625         break;
626       }
627 #endif
628
629       cp += len;
630       if (strlen(cp) == 0)
631         cp = NULL;
632       else
633         cp++;
634
635       if (item)
636         silc_free(item);
637     }
638   }
639
640   payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
641     2 + payload->version_len +
642     2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
643     2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
644     2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
645
646   /* Save our reply payload */
647   ske->start_payload = payload;
648
649   return SILC_SKE_STATUS_OK;
650 }
651
652 /* Creates random number such that 1 < rnd < n and at most length
653    of len bits. The rnd sent as argument must be initialized. */
654
655 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
656                                          SilcUInt32 len,
657                                          SilcMPInt *rnd)
658 {
659   SilcSKEStatus status = SILC_SKE_STATUS_OK;
660   unsigned char *string;
661   SilcUInt32 l;
662
663   if (!len)
664     return SILC_SKE_STATUS_ERROR;
665
666   SILC_LOG_DEBUG(("Creating random number"));
667
668   l = ((len - 1) / 8);
669
670   /* Get the random number as string */
671   string = silc_rng_get_rn_data(ske->rng, l);
672   if (!string)
673     return SILC_SKE_STATUS_OUT_OF_MEMORY;
674
675   /* Decode the string into a MP integer */
676   silc_mp_bin2mp(string, l, rnd);
677   silc_mp_mod_2exp(rnd, rnd, len);
678
679   /* Checks */
680   if (silc_mp_cmp_ui(rnd, 1) < 0)
681     status = SILC_SKE_STATUS_ERROR;
682   if (silc_mp_cmp(rnd, n) >= 0)
683     status = SILC_SKE_STATUS_ERROR;
684
685   memset(string, 'F', l);
686   silc_free(string);
687
688   return status;
689 }
690
691 /* Creates a hash value HASH as defined in the SKE protocol. If the
692    `initiator' is TRUE then this function is used to create the HASH_i
693    hash value defined in the protocol. If it is FALSE then this is used
694    to create the HASH value defined by the protocol. */
695
696 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
697                                         unsigned char *return_hash,
698                                         SilcUInt32 *return_hash_len,
699                                         int initiator)
700 {
701   SilcSKEStatus status = SILC_SKE_STATUS_OK;
702   SilcBuffer buf;
703   unsigned char *e, *f, *KEY, *s_data;
704   SilcUInt32 e_len, f_len, KEY_len, s_len;
705   int ret;
706
707   SILC_LOG_DEBUG(("Start"));
708
709   if (initiator == FALSE) {
710     s_data = (ske->start_payload_copy ?
711              silc_buffer_data(ske->start_payload_copy) : NULL);
712     s_len = (ske->start_payload_copy ?
713              silc_buffer_len(ske->start_payload_copy) : 0);
714     e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
715     if (!e)
716       return SILC_SKE_STATUS_OUT_OF_MEMORY;
717     f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
718     if (!f)
719       return SILC_SKE_STATUS_OUT_OF_MEMORY;
720     KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
721     if (!KEY)
722       return SILC_SKE_STATUS_OUT_OF_MEMORY;
723
724     /* Format the buffer used to compute the hash value */
725     buf = silc_buffer_alloc_size(s_len +
726                                  ske->ke2_payload->pk_len +
727                                  ske->ke1_payload->pk_len +
728                                  e_len + f_len + KEY_len);
729     if (!buf)
730       return SILC_SKE_STATUS_OUT_OF_MEMORY;
731
732     /* Initiator is not required to send its public key */
733     if (!ske->ke1_payload->pk_data) {
734       ret =
735         silc_buffer_format(buf,
736                            SILC_STR_DATA(s_data, s_len),
737                            SILC_STR_DATA(ske->ke2_payload->pk_data,
738                                          ske->ke2_payload->pk_len),
739                            SILC_STR_DATA(e, e_len),
740                            SILC_STR_DATA(f, f_len),
741                            SILC_STR_DATA(KEY, KEY_len),
742                            SILC_STR_END);
743     } else {
744       ret =
745         silc_buffer_format(buf,
746                            SILC_STR_DATA(s_data, s_len),
747                            SILC_STR_DATA(ske->ke2_payload->pk_data,
748                                          ske->ke2_payload->pk_len),
749                            SILC_STR_DATA(ske->ke1_payload->pk_data,
750                                          ske->ke1_payload->pk_len),
751                            SILC_STR_DATA(e, e_len),
752                            SILC_STR_DATA(f, f_len),
753                            SILC_STR_DATA(KEY, KEY_len),
754                            SILC_STR_END);
755     }
756     if (ret == -1) {
757       silc_buffer_free(buf);
758       memset(e, 0, e_len);
759       memset(f, 0, f_len);
760       memset(KEY, 0, KEY_len);
761       silc_free(e);
762       silc_free(f);
763       silc_free(KEY);
764       return SILC_SKE_STATUS_ERROR;
765     }
766
767     memset(e, 0, e_len);
768     memset(f, 0, f_len);
769     memset(KEY, 0, KEY_len);
770     silc_free(e);
771     silc_free(f);
772     silc_free(KEY);
773   } else {
774     s_data = (ske->start_payload_copy ?
775              silc_buffer_data(ske->start_payload_copy) : NULL);
776     s_len = (ske->start_payload_copy ?
777              silc_buffer_len(ske->start_payload_copy) : 0);
778     e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
779     if (!e)
780       return SILC_SKE_STATUS_OUT_OF_MEMORY;
781
782     buf = silc_buffer_alloc_size(s_len + ske->ke1_payload->pk_len + e_len);
783     if (!buf)
784       return SILC_SKE_STATUS_OUT_OF_MEMORY;
785
786     /* Format the buffer used to compute the hash value */
787     ret =
788       silc_buffer_format(buf,
789                          SILC_STR_DATA(s_data, s_len),
790                          SILC_STR_DATA(ske->ke1_payload->pk_data,
791                                        ske->ke1_payload->pk_len),
792                          SILC_STR_DATA(e, e_len),
793                          SILC_STR_END);
794     if (ret == -1) {
795       silc_buffer_free(buf);
796       memset(e, 0, e_len);
797       silc_free(e);
798       return SILC_SKE_STATUS_ERROR;
799     }
800
801     SILC_LOG_HEXDUMP(("hash buf"), buf->data, silc_buffer_len(buf));
802
803     memset(e, 0, e_len);
804     silc_free(e);
805   }
806
807   /* Make the hash */
808   silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
809                  return_hash);
810   *return_hash_len = silc_hash_len(ske->prop->hash);
811
812   if (initiator == FALSE) {
813     SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
814   } else {
815     SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
816   }
817
818   silc_buffer_free(buf);
819
820   return status;
821 }
822
823 /* Generate rekey material */
824
825 static SilcSKERekeyMaterial
826 silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
827 {
828   SilcSKERekeyMaterial rekey;
829   const char *hash;
830
831   if (!keymat)
832     return NULL;
833
834   /* Create rekey material */
835   rekey = silc_calloc(1, sizeof(*rekey));
836   if (!rekey)
837     return NULL;
838
839   if (ske->prop) {
840     if (ske->prop->group)
841       rekey->ske_group = silc_ske_group_get_number(ske->prop->group);
842     rekey->pfs = (ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? TRUE : FALSE);
843     hash = silc_hash_get_name(ske->prop->hash);
844     rekey->hash = silc_memdup(hash, strlen(hash));
845     if (!rekey->hash)
846       return NULL;
847   }
848
849   if (rekey->pfs == FALSE) {
850     rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
851                                       keymat->enc_key_len / 8);
852     if (!rekey->send_enc_key) {
853       silc_free(rekey);
854       return NULL;
855     }
856     rekey->enc_key_len = keymat->enc_key_len;
857   }
858
859   return rekey;
860 }
861
862 /* Assembles security properties */
863
864 static SilcSKEStartPayload
865 silc_ske_assemble_security_properties(SilcSKE ske,
866                                       SilcSKESecurityPropertyFlag flags,
867                                       const char *version)
868 {
869   SilcSKEStartPayload rp;
870   int i;
871
872   SILC_LOG_DEBUG(("Assembling KE Start Payload"));
873
874   rp = silc_calloc(1, sizeof(*rp));
875   if (!rp)
876     return NULL;
877
878   /* Set flags */
879   rp->flags = (unsigned char)flags;
880
881   /* Set random cookie */
882   rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
883   if (!rp->cookie) {
884     silc_free(rp);
885     return NULL;
886   }
887   for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
888     rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
889   rp->cookie_len = SILC_SKE_COOKIE_LEN;
890
891   /* In case IV included flag and session port is set the first 16-bits of
892      cookie will include our session port. */
893   if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
894     SILC_PUT16_MSB(ske->session_port, rp->cookie);
895
896   /* Put version */
897   rp->version = strdup(version);
898   if (rp->version)
899     rp->version_len = strlen(version);
900
901   /* Get supported Key Exhange groups */
902   rp->ke_grp_list = silc_ske_get_supported_groups();
903   if (rp->ke_grp_list)
904     rp->ke_grp_len = strlen(rp->ke_grp_list);
905
906   /* Get supported PKCS algorithms */
907   rp->pkcs_alg_list = silc_pkcs_get_supported();
908   if (rp->pkcs_alg_list)
909     rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
910
911   /* Get supported encryption algorithms */
912   rp->enc_alg_list = silc_cipher_get_supported();
913   if (rp->enc_alg_list)
914     rp->enc_alg_len = strlen(rp->enc_alg_list);
915
916   /* Get supported hash algorithms */
917   rp->hash_alg_list = silc_hash_get_supported();
918   if (rp->hash_alg_list)
919     rp->hash_alg_len = strlen(rp->hash_alg_list);
920
921   /* Get supported HMACs */
922   rp->hmac_alg_list = silc_hmac_get_supported();
923   if (rp->hmac_alg_list)
924     rp->hmac_alg_len = strlen(rp->hmac_alg_list);
925
926   /* XXX */
927   /* Get supported compression algorithms */
928   rp->comp_alg_list = strdup("none");
929   rp->comp_alg_len = strlen("none");
930
931   rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
932     2 + rp->version_len +
933     2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
934     2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
935     2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
936
937   return rp;
938 }
939
940 /* Packet retransmission callback. */
941
942 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
943 {
944   SilcSKE ske = context;
945
946   if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
947       ske->aborted) {
948     SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
949     ske->retry_count = 0;
950     ske->retry_timer = SILC_SKE_RETRY_MIN;
951     silc_free(ske->retrans.data);
952     ske->retrans.data = NULL;
953     ske->status = SILC_SKE_STATUS_TIMEOUT;
954          silc_ske_notify_failure(ske);
955     silc_fsm_continue_sync(&ske->fsm);
956     return;
957   }
958
959   SILC_LOG_DEBUG(("Retransmitting packet"));
960   silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
961                        ske->retrans.data, ske->retrans.data_len);
962 }
963
964 /* Install retransmission timer */
965
966 static void silc_ske_install_retransmission(SilcSKE ske)
967 {
968   if (!silc_packet_stream_is_udp(ske->stream))
969     return;
970
971   if (ske->retrans.data) {
972     SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
973                     ske->retry_timer));
974     silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
975                                    ske, ske->retry_timer, 0);
976   }
977   ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
978                       (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
979 }
980
981 /* Sends SILC packet.  Handles retransmissions with UDP streams. */
982
983 static SilcBool silc_ske_packet_send(SilcSKE ske,
984                                      SilcPacketType type,
985                                      SilcPacketFlags flags,
986                                      const unsigned char *data,
987                                      SilcUInt32 data_len)
988 {
989   SilcBool ret;
990
991   /* Send the packet */
992   ret = silc_packet_send(ske->stream, type, flags, data, data_len);
993
994   if (silc_packet_stream_is_udp(ske->stream) &&
995       type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
996     silc_free(ske->retrans.data);
997     ske->retrans.type = type;
998     ske->retrans.flags = flags;
999     ske->retrans.data = silc_memdup(data, data_len);
1000     if (ske->retrans.data) {
1001       ske->retrans.data_len = data_len;
1002       silc_ske_install_retransmission(ske);
1003     }
1004   }
1005
1006   return ret;
1007 }
1008
1009 /* Calls completion callback.  Completion is called always in this function
1010    and must not be called anywhere else. */
1011
1012 static void silc_ske_completion(SilcSKE ske)
1013 {
1014   /* Call the completion callback */
1015   if (!ske->aborted && ske->callbacks->completed) {
1016     if (ske->status != SILC_SKE_STATUS_OK)
1017       ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1018                                 ske->callbacks->context);
1019     else
1020       ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1021                                 ske->rekey, ske->callbacks->context);
1022   }
1023 }
1024
1025 /* SKE FSM destructor. */
1026
1027 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1028                               void *destructor_context)
1029 {
1030   SilcSKE ske = fsm_context;
1031   silc_ske_free(ske);
1032 }
1033
1034 /* Key exchange timeout task callback */
1035
1036 SILC_TASK_CALLBACK(silc_ske_timeout)
1037 {
1038   SilcSKE ske = context;
1039
1040   SILC_LOG_DEBUG(("Timeout"));
1041
1042   ske->packet = NULL;
1043   ske->status = SILC_SKE_STATUS_TIMEOUT;
1044   silc_ske_notify_failure(ske);
1045
1046   silc_fsm_continue_sync(&ske->fsm);
1047 }
1048
1049 /******************************* Protocol API *******************************/
1050
1051 /* Allocates new SKE object. */
1052
1053 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1054                        SilcSKR repository, SilcPublicKey public_key,
1055                        SilcPrivateKey private_key, void *context)
1056 {
1057   SilcSKE ske;
1058
1059   SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1060
1061   if (!rng || !schedule)
1062     return NULL;
1063
1064   if (!public_key) {
1065     SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1066     return NULL;
1067   }
1068
1069   ske = silc_calloc(1, sizeof(*ske));
1070   if (!ske)
1071     return NULL;
1072   ske->status = SILC_SKE_STATUS_OK;
1073   ske->rng = rng;
1074   ske->repository = repository;
1075   ske->user_data = context;
1076   ske->schedule = schedule;
1077   ske->public_key = public_key;
1078   ske->private_key = private_key;
1079   ske->retry_timer = SILC_SKE_RETRY_MIN;
1080   ske->refcnt = 1;
1081
1082   return ske;
1083 }
1084
1085 /* Free's SKE object. */
1086
1087 void silc_ske_free(SilcSKE ske)
1088 {
1089   if (!ske)
1090     return;
1091
1092   SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu",
1093                   ske, ske->aborted, ske->refcnt));
1094
1095   if (ske->aborted) {
1096     /*
1097      * If already aborted, destroy the session immediately.  Only do the
1098      * notification work if we have not already though, as doing so twice
1099      * results in memory corruption.  We may have silc_ske_free called
1100      * twice, once when the abort is requested, and then again when the
1101      * FSM finish routine is called.  We have to be prepared to handle
1102      * that case.
1103      */
1104     ske->packet = NULL;
1105     ske->status = SILC_SKE_STATUS_ERROR;
1106
1107     silc_ske_notify_failure(ske);
1108
1109     if (silc_fsm_is_started(&ske->fsm))
1110       silc_fsm_continue_sync(&ske->fsm);
1111     else
1112       SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1113   }
1114
1115   ske->refcnt--;
1116   if (ske->refcnt > 0)
1117     return;
1118
1119   /* Free start payload */
1120   if (ske->start_payload)
1121     silc_ske_payload_start_free(ske->start_payload);
1122
1123   /* Free KE payload */
1124   if (ske->ke1_payload)
1125     silc_ske_payload_ke_free(ske->ke1_payload);
1126   if (ske->ke2_payload)
1127     silc_ske_payload_ke_free(ske->ke2_payload);
1128   silc_free(ske->remote_version);
1129
1130   /* Free rest */
1131   if (ske->prop) {
1132     if (ske->prop->group)
1133       silc_ske_group_free(ske->prop->group);
1134     if (ske->prop->cipher)
1135       silc_cipher_free(ske->prop->cipher);
1136     if (ske->prop->hash)
1137       silc_hash_free(ske->prop->hash);
1138     if (ske->prop->hmac)
1139       silc_hmac_free(ske->prop->hmac);
1140     if (ske->prop->public_key)
1141       silc_pkcs_public_key_free(ske->prop->public_key);
1142     silc_free(ske->prop);
1143   }
1144   if (ske->keymat)
1145     silc_ske_free_key_material(ske->keymat);
1146   if (ske->start_payload_copy)
1147     silc_buffer_free(ske->start_payload_copy);
1148   if (ske->x) {
1149     silc_mp_uninit(ske->x);
1150     silc_free(ske->x);
1151   }
1152   if (ske->KEY) {
1153     silc_mp_uninit(ske->KEY);
1154     silc_free(ske->KEY);
1155   }
1156   silc_free(ske->retrans.data);
1157   silc_free(ske->hash);
1158   silc_free(ske->callbacks);
1159
1160   memset(ske, 0xdd, sizeof(*ske));
1161   silc_free(ske);
1162 }
1163
1164 /* Return user context */
1165
1166 void *silc_ske_get_context(SilcSKE ske)
1167 {
1168   return ske->user_data;
1169 }
1170
1171 /* Sets protocol callbacks */
1172
1173 void silc_ske_set_callbacks(SilcSKE ske,
1174                             SilcSKEVerifyCb verify_key,
1175                             SilcSKECompletionCb completed,
1176                             void *context)
1177 {
1178   if (ske->callbacks)
1179     silc_free(ske->callbacks);
1180   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1181   if (!ske->callbacks)
1182     return;
1183   ske->callbacks->verify_key = verify_key;
1184   ske->callbacks->completed = completed;
1185   ske->callbacks->context = context;
1186 }
1187
1188
1189 /******************************** Initiator *********************************/
1190
1191 /* Start protocol.  Send our proposal */
1192
1193 SILC_FSM_STATE(silc_ske_st_initiator_start)
1194 {
1195   SilcSKE ske = fsm_context;
1196   SilcBuffer payload_buf;
1197   SilcStatus status;
1198
1199   SILC_LOG_DEBUG(("Start"));
1200
1201   if (ske->aborted) {
1202     /** Aborted */
1203     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1204     return SILC_FSM_CONTINUE;
1205   }
1206
1207   /* Encode the payload */
1208   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1209                                          &payload_buf);
1210   if (status != SILC_SKE_STATUS_OK) {
1211     /** Error encoding Start Payload */
1212     ske->status = status;
1213     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1214     return SILC_FSM_CONTINUE;
1215   }
1216
1217   /* Save the the payload buffer for future use. It is later used to
1218      compute the HASH value. */
1219   ske->start_payload_copy = payload_buf;
1220
1221   /* Send the packet. */
1222   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1223                             silc_buffer_data(payload_buf),
1224                             silc_buffer_len(payload_buf))) {
1225     /** Error sending packet */
1226     SILC_LOG_DEBUG(("Error sending packet"));
1227     ske->status = SILC_SKE_STATUS_ERROR;
1228     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1229     return SILC_FSM_CONTINUE;
1230   }
1231
1232   /* Add key exchange timeout */
1233   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1234                                  ske, ske->timeout, 0);
1235
1236   /** Wait for responder proposal */
1237   SILC_LOG_DEBUG(("Waiting for responder proposal"));
1238   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1239   return SILC_FSM_WAIT;
1240 }
1241
1242 /* Phase-1.  Receives responder's proposal */
1243
1244 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1245 {
1246   SilcSKE ske = fsm_context;
1247   SilcSKEStatus status;
1248   SilcSKEStartPayload payload;
1249   SilcSKESecurityProperties prop;
1250   SilcSKEDiffieHellmanGroup group = NULL;
1251   SilcBuffer packet_buf = &ske->packet->buffer;
1252   SilcUInt16 remote_port = 0;
1253   SilcID id;
1254   int coff = 0;
1255
1256   SILC_LOG_DEBUG(("Start"));
1257
1258   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1259     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1260     silc_ske_install_retransmission(ske);
1261     silc_packet_free(ske->packet);
1262     ske->packet = NULL;
1263     return SILC_FSM_WAIT;
1264   }
1265
1266   /* Decode the payload */
1267   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1268   if (status != SILC_SKE_STATUS_OK) {
1269     /** Error decoding Start Payload */
1270     silc_packet_free(ske->packet);
1271     ske->packet = NULL;
1272     ske->status = status;
1273     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1274     return SILC_FSM_CONTINUE;
1275   }
1276
1277   /* Get remote ID and set it to stream */
1278   if (ske->packet->src_id_len) {
1279     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1280                    ske->packet->src_id_type,
1281                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1282                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1283                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1284                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1285     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1286                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1287                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1288   }
1289
1290   silc_packet_free(ske->packet);
1291   ske->packet = NULL;
1292
1293   /* Check that the cookie is returned unmodified.  In case IV included
1294      flag and session port has been set, the first two bytes of cookie
1295      are the session port and we ignore them in this check. */
1296   if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1297     /* Take remote port */
1298     SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1299     coff = 2;
1300   }
1301   if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1302              SILC_SKE_COOKIE_LEN - coff)) {
1303     /** Invalid cookie */
1304     SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1305     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1306     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1307     return SILC_FSM_CONTINUE;
1308   }
1309
1310   /* Check version string */
1311   ske->remote_version = silc_memdup(payload->version, payload->version_len);
1312   status = silc_ske_check_version(ske);
1313   if (status != SILC_SKE_STATUS_OK) {
1314     /** Version mismatch */
1315     ske->status = status;
1316     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1317     return SILC_FSM_CONTINUE;
1318   }
1319
1320   /* Free our KE Start Payload context, we don't need it anymore. */
1321   silc_ske_payload_start_free(ske->start_payload);
1322   ske->start_payload = NULL;
1323
1324   /* Take the selected security properties into use while doing
1325      the key exchange.  This is used only while doing the key
1326      exchange. */
1327   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1328   if (!ske->prop)
1329     goto err;
1330   prop->flags = payload->flags;
1331   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1332   if (status != SILC_SKE_STATUS_OK)
1333     goto err;
1334
1335   prop->group = group;
1336   prop->remote_port = remote_port;
1337
1338   if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1339     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1340     goto err;
1341   }
1342   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1343     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1344     goto err;
1345   }
1346   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1347     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1348     goto err;
1349   }
1350   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1351     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1352     goto err;
1353   }
1354
1355   /* Save remote's KE Start Payload */
1356   ske->start_payload = payload;
1357
1358   /** Send KE Payload */
1359   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1360   return SILC_FSM_CONTINUE;
1361
1362  err:
1363   if (payload)
1364     silc_ske_payload_start_free(payload);
1365   if (group)
1366     silc_ske_group_free(group);
1367   if (prop) {
1368     if (prop->cipher)
1369       silc_cipher_free(prop->cipher);
1370     if (prop->hash)
1371       silc_hash_free(prop->hash);
1372     if (prop->hmac)
1373       silc_hmac_free(prop->hmac);
1374     silc_free(prop);
1375   }
1376   ske->prop = NULL;
1377
1378   if (status == SILC_SKE_STATUS_OK)
1379     status = SILC_SKE_STATUS_ERROR;
1380
1381   /** Error */
1382   ske->status = status;
1383   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1384   return SILC_FSM_CONTINUE;
1385 }
1386
1387 /* Phase-2.  Send KE payload */
1388
1389 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1390 {
1391   SilcSKE ske = fsm_context;
1392   SilcSKEStatus status;
1393   SilcBuffer payload_buf;
1394   SilcMPInt *x;
1395   SilcSKEKEPayload payload;
1396   SilcUInt32 pk_len;
1397
1398   SILC_LOG_DEBUG(("Start"));
1399
1400   /* Create the random number x, 1 < x < q. */
1401   x = silc_calloc(1, sizeof(*x));
1402   if (!x) {
1403     /** Out of memory */
1404     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1405     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1406     return SILC_FSM_CONTINUE;
1407   }
1408   silc_mp_init(x);
1409   status =
1410     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1411                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1412                         x);
1413   if (status != SILC_SKE_STATUS_OK) {
1414     /** Error generating random number */
1415     silc_mp_uninit(x);
1416     silc_free(x);
1417     ske->status = status;
1418     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1419     return SILC_FSM_CONTINUE;
1420   }
1421
1422   /* Encode the result to Key Exchange Payload. */
1423
1424   payload = silc_calloc(1, sizeof(*payload));
1425   if (!payload) {
1426     /** Out of memory */
1427     silc_mp_uninit(x);
1428     silc_free(x);
1429     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1430     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1431     return SILC_FSM_CONTINUE;
1432   }
1433   ske->ke1_payload = payload;
1434
1435   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1436
1437   /* Do the Diffie Hellman computation, e = g ^ x mod p */
1438   silc_mp_init(&payload->x);
1439   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1440                   &ske->prop->group->group);
1441
1442   /* Get public key */
1443   payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1444   if (!payload->pk_data) {
1445     /** Error encoding public key */
1446     silc_mp_uninit(x);
1447     silc_free(x);
1448     silc_mp_uninit(&payload->x);
1449     silc_free(payload);
1450     ske->ke1_payload = NULL;
1451     ske->status = SILC_SKE_STATUS_ERROR;
1452     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1453     return SILC_FSM_CONTINUE;
1454   }
1455   payload->pk_len = pk_len;
1456   payload->pk_type = silc_pkcs_get_type(ske->public_key);
1457
1458   /* Compute signature data if we are doing mutual authentication */
1459   if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1460     unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1];
1461     SilcUInt32 hash_len, sign_len;
1462
1463     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1464     SILC_LOG_DEBUG(("Computing HASH_i value"));
1465
1466     /* Compute the hash value */
1467     memset(hash, 0, sizeof(hash));
1468     if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK)
1469       {
1470         /** Error computing hash */
1471         silc_mp_uninit(x);
1472         silc_free(x);
1473         silc_mp_uninit(&payload->x);
1474         silc_free(payload->pk_data);
1475         silc_free(payload);
1476         ske->ke1_payload = NULL;
1477         ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1478         silc_fsm_next(fsm, silc_ske_st_initiator_error);
1479         return SILC_FSM_CONTINUE;
1480       }
1481
1482     SILC_LOG_DEBUG(("Signing HASH_i value"));
1483
1484     /* Sign the hash value */
1485     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1486                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1487       /** Error computing signature */
1488       silc_mp_uninit(x);
1489       silc_free(x);
1490       silc_mp_uninit(&payload->x);
1491       silc_free(payload->pk_data);
1492       silc_free(payload);
1493       ske->ke1_payload = NULL;
1494       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1495       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1496       return SILC_FSM_CONTINUE;
1497     }
1498     payload->sign_data = silc_memdup(sign, sign_len);
1499     if (payload->sign_data)
1500       payload->sign_len = sign_len;
1501     memset(sign, 0, sizeof(sign));
1502   }
1503
1504   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1505   if (status != SILC_SKE_STATUS_OK) {
1506     /** Error encoding KE payload */
1507     silc_mp_uninit(x);
1508     silc_free(x);
1509     silc_mp_uninit(&payload->x);
1510     silc_free(payload->pk_data);
1511     silc_free(payload->sign_data);
1512     silc_free(payload);
1513     ske->ke1_payload = NULL;
1514     ske->status = status;
1515     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1516     return SILC_FSM_CONTINUE;
1517   }
1518
1519   ske->x = x;
1520
1521   /* Check for backwards compatibility */
1522
1523   /* Send the packet. */
1524   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1525                             silc_buffer_data(payload_buf),
1526                             silc_buffer_len(payload_buf))) {
1527     /** Error sending packet */
1528     SILC_LOG_DEBUG(("Error sending packet"));
1529     ske->status = SILC_SKE_STATUS_ERROR;
1530     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1531     return SILC_FSM_CONTINUE;
1532   }
1533
1534   silc_buffer_free(payload_buf);
1535
1536   /** Waiting responder's KE payload */
1537   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1538   return SILC_FSM_WAIT;
1539 }
1540
1541 /* Phase-3.  Process responder's KE payload */
1542
1543 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1544 {
1545   SilcSKE ske = fsm_context;
1546   SilcSKEStatus status;
1547   SilcSKEKEPayload payload;
1548   SilcMPInt *KEY;
1549   SilcBuffer packet_buf = &ske->packet->buffer;
1550
1551   SILC_LOG_DEBUG(("Start"));
1552
1553   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1554     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1555     silc_ske_install_retransmission(ske);
1556     silc_packet_free(ske->packet);
1557     ske->packet = NULL;
1558     return SILC_FSM_WAIT;
1559   }
1560
1561   /* Decode the payload */
1562   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1563   if (status != SILC_SKE_STATUS_OK) {
1564     /** Error decoding KE payload */
1565     silc_packet_free(ske->packet);
1566     ske->packet = NULL;
1567     ske->status = status;
1568     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1569     return SILC_FSM_CONTINUE;
1570   }
1571   silc_packet_free(ske->packet);
1572   ske->packet = NULL;
1573   ske->ke2_payload = payload;
1574
1575   if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1576     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1577                     "even though we require it"));
1578     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1579     goto err;
1580   }
1581
1582   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1583
1584   /* Compute the shared secret key */
1585   KEY = silc_calloc(1, sizeof(*KEY));
1586   if (!KEY) {
1587     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1588     goto err;
1589   }
1590   silc_mp_init(KEY);
1591   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1592   ske->KEY = KEY;
1593
1594   /* Decode the remote's public key */
1595   if (payload->pk_data &&
1596       !silc_pkcs_public_key_alloc(payload->pk_type,
1597                                   payload->pk_data, payload->pk_len,
1598                                   &ske->prop->public_key)) {
1599     SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1600     status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1601     goto err;
1602   }
1603
1604   if (ske->prop->public_key && (ske->callbacks->verify_key ||
1605                                 ske->repository)) {
1606     SILC_LOG_DEBUG(("Verifying public key"));
1607
1608     /** Waiting public key verification */
1609     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1610
1611     /* If repository is provided, verify the key from there. */
1612     if (ske->repository) {
1613       SilcSKRFind find;
1614
1615       find = silc_skr_find_alloc();
1616       if (!find) {
1617         status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1618         goto err;
1619       }
1620       silc_skr_find_set_pkcs_type(find,
1621                                   silc_pkcs_get_type(ske->prop->public_key));
1622       silc_skr_find_set_public_key(find, ske->prop->public_key);
1623       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1624
1625       /* Find key from repository */
1626       SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1627                                   find, silc_ske_skr_callback, ske));
1628     } else {
1629       /* Verify from application */
1630       SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1631                                                ske->callbacks->context,
1632                                                silc_ske_pk_verified, NULL));
1633     }
1634     /* NOT REACHED */
1635   }
1636
1637   /** Process key material */
1638   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1639   return SILC_FSM_CONTINUE;
1640
1641  err:
1642   silc_ske_payload_ke_free(payload);
1643   ske->ke2_payload = NULL;
1644
1645   silc_mp_uninit(ske->KEY);
1646   silc_free(ske->KEY);
1647   ske->KEY = NULL;
1648
1649   if (status == SILC_SKE_STATUS_OK)
1650     return SILC_SKE_STATUS_ERROR;
1651
1652   /** Error */
1653   ske->status = status;
1654   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1655   return SILC_FSM_CONTINUE;
1656 }
1657
1658 /* Process key material */
1659
1660 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1661 {
1662   SilcSKE ske = fsm_context;
1663   SilcSKEStatus status;
1664   SilcSKEKEPayload payload;
1665   unsigned char hash[SILC_HASH_MAXLEN];
1666   SilcUInt32 hash_len;
1667   int key_len, block_len;
1668
1669   if (ske->aborted) {
1670     /** Aborted */
1671     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1672     return SILC_FSM_CONTINUE;
1673   }
1674
1675   /* Check result of public key verification */
1676   if (ske->status != SILC_SKE_STATUS_OK) {
1677     /** Public key not verified */
1678     SILC_LOG_DEBUG(("Public key verification failed"));
1679     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1680     return SILC_FSM_CONTINUE;
1681   }
1682
1683   payload = ske->ke2_payload;
1684
1685   /* Compute the HASH value */
1686   SILC_LOG_DEBUG(("Computing HASH value"));
1687   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1688   if (status != SILC_SKE_STATUS_OK)
1689     goto err;
1690   ske->hash = silc_memdup(hash, hash_len);
1691   if (!ske->hash) {
1692     status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1693     goto err;
1694   }
1695   ske->hash_len = hash_len;
1696
1697   if (ske->prop->public_key) {
1698     SILC_LOG_DEBUG(("Public key is authentic"));
1699     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1700
1701     /* Verify signature */
1702     if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1703                           payload->sign_len, hash, hash_len, NULL)) {
1704       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1705       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1706       goto err;
1707     }
1708
1709     SILC_LOG_DEBUG(("Signature is Ok"));
1710     memset(hash, 'F', hash_len);
1711   }
1712
1713   ske->status = SILC_SKE_STATUS_OK;
1714
1715   /* In case we are doing rekey move to finish it.  */
1716   if (ske->rekey) {
1717     /** Finish rekey */
1718     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1719     return SILC_FSM_CONTINUE;
1720   }
1721
1722   /* Process key material */
1723   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1724   block_len = silc_cipher_get_block_len(ske->prop->cipher);
1725   hash_len = silc_hash_len(ske->prop->hash);
1726   ske->keymat = silc_ske_process_key_material(ske, block_len,
1727                                               key_len, hash_len,
1728                                               &ske->rekey);
1729   if (!ske->keymat) {
1730     SILC_LOG_ERROR(("Error processing key material"));
1731     status = SILC_SKE_STATUS_ERROR;
1732     goto err;
1733   }
1734
1735   /* Send SUCCESS packet */
1736   SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1737   if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1738     /** Error sending packet */
1739     SILC_LOG_DEBUG(("Error sending packet"));
1740     ske->status = SILC_SKE_STATUS_ERROR;
1741     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1742     return SILC_FSM_CONTINUE;
1743   }
1744
1745   /** Waiting completion */
1746   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1747   return SILC_FSM_WAIT;
1748
1749  err:
1750   memset(hash, 'F', sizeof(hash));
1751   silc_ske_payload_ke_free(payload);
1752   ske->ke2_payload = NULL;
1753
1754   silc_mp_uninit(ske->KEY);
1755   silc_free(ske->KEY);
1756   ske->KEY = NULL;
1757
1758   if (ske->hash) {
1759     memset(ske->hash, 'F', hash_len);
1760     silc_free(ske->hash);
1761     ske->hash = NULL;
1762   }
1763
1764   if (status == SILC_SKE_STATUS_OK)
1765     status = SILC_SKE_STATUS_ERROR;
1766
1767   /** Error */
1768   ske->status = status;
1769   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1770   return SILC_FSM_CONTINUE;
1771 }
1772
1773 /* Protocol completed */
1774
1775 SILC_FSM_STATE(silc_ske_st_initiator_end)
1776 {
1777   SilcSKE ske = fsm_context;
1778
1779   SILC_LOG_DEBUG(("Start"));
1780
1781   if (ske->packet->type != SILC_PACKET_SUCCESS) {
1782     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1783     silc_ske_install_retransmission(ske);
1784     silc_packet_free(ske->packet);
1785     ske->packet = NULL;
1786     return SILC_FSM_WAIT;
1787   }
1788
1789   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1790
1791   silc_packet_free(ske->packet);
1792   ske->packet = NULL;
1793   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1794   silc_schedule_task_del_by_context(ske->schedule, ske);
1795
1796   /* Call completion */
1797   silc_ske_completion(ske);
1798
1799   return SILC_FSM_FINISH;
1800 }
1801
1802 /* Aborted by application */
1803
1804 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1805 {
1806   SilcSKE ske = fsm_context;
1807   unsigned char data[4];
1808
1809   SILC_LOG_DEBUG(("Aborted by caller"));
1810
1811   /* Send FAILURE packet */
1812   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1813   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1814
1815   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1816   silc_schedule_task_del_by_context(ske->schedule, ske);
1817
1818   /* Call completion */
1819   silc_ske_completion(ske);
1820
1821   return SILC_FSM_FINISH;
1822 }
1823
1824 /* Error occurred.  Send error to remote host */
1825
1826 SILC_FSM_STATE(silc_ske_st_initiator_error)
1827 {
1828   SilcSKE ske = fsm_context;
1829   SilcSKEStatus status;
1830   unsigned char data[4];
1831
1832   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1833                   silc_ske_map_status(ske->status), ske->status));
1834
1835   status = ske->status;
1836   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1837     status = SILC_SKE_STATUS_ERROR;
1838
1839   /* Send FAILURE packet */
1840   SILC_PUT32_MSB((SilcUInt32)status, data);
1841   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1842
1843   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1844   silc_schedule_task_del_by_context(ske->schedule, ske);
1845
1846   /* Call completion */
1847   silc_ske_completion(ske);
1848
1849   return SILC_FSM_FINISH;
1850 }
1851
1852 /* Failure received from remote */
1853
1854 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1855 {
1856   SilcSKE ske = fsm_context;
1857   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1858
1859   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1860     SILC_GET32_MSB(error, ske->packet->buffer.data);
1861     silc_packet_free(ske->packet);
1862     ske->packet = NULL;
1863   }
1864   ske->status = error;
1865
1866   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1867                   silc_ske_map_status(ske->status), ske->status));
1868
1869   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1870   silc_schedule_task_del_by_context(ske->schedule, ske);
1871
1872   /* Call completion */
1873   silc_ske_completion(ske);
1874
1875   return SILC_FSM_FINISH;
1876 }
1877
1878 /* Starts the protocol as initiator */
1879
1880 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1881                                       SilcPacketStream stream,
1882                                       SilcSKEParams params,
1883                                       SilcSKEStartPayload start_payload)
1884 {
1885   SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; "
1886                   "start_payload=%p", ske, stream, params, start_payload));
1887
1888   if (!ske || !stream || !params || !params->version)
1889     return NULL;
1890
1891   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1892     return NULL;
1893
1894   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1895     return NULL;
1896
1897   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1898     ske->session_port = params->session_port;
1899
1900   /* Generate security properties if not provided */
1901   if (!start_payload) {
1902     start_payload = silc_ske_assemble_security_properties(ske,
1903                                                           params->flags,
1904                                                           params->version);
1905     if (!start_payload)
1906       return NULL;
1907   }
1908
1909   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1910   ske->start_payload = start_payload;
1911   ske->version = params->version;
1912   ++ske->refcnt;
1913
1914   /* Link to packet stream to get key exchange packets */
1915   ske->stream = stream;
1916   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1917                           SILC_PACKET_KEY_EXCHANGE,
1918                           SILC_PACKET_KEY_EXCHANGE_2,
1919                           SILC_PACKET_SUCCESS,
1920                           SILC_PACKET_FAILURE, -1);
1921
1922   /* Start SKE as initiator */
1923   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1924
1925   return &ske->op;
1926 }
1927
1928 /******************************** Responder *********************************/
1929
1930 /* Start protocol as responder.  Wait initiator's start payload */
1931
1932 SILC_FSM_STATE(silc_ske_st_responder_start)
1933 {
1934   SilcSKE ske = fsm_context;
1935
1936   SILC_LOG_DEBUG(("Start"));
1937
1938   if (ske->aborted) {
1939     /** Aborted */
1940     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1941     return SILC_FSM_CONTINUE;
1942   }
1943
1944   /* Add key exchange timeout */
1945   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1946                                  ske, ske->timeout, 0);
1947
1948   /** Wait for initiator */
1949   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1950   return SILC_FSM_WAIT;
1951 }
1952
1953 /* Decode initiator's start payload.  Select the security properties from
1954    the initiator's start payload and send our reply start payload back. */
1955
1956 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1957 {
1958   SilcSKE ske = fsm_context;
1959   SilcSKEStatus status;
1960   SilcSKEStartPayload remote_payload = NULL;
1961   SilcBuffer packet_buf = &ske->packet->buffer;
1962   SilcID id;
1963
1964   SILC_LOG_DEBUG(("Start"));
1965
1966   /* Decode the payload */
1967   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1968   if (status != SILC_SKE_STATUS_OK) {
1969     /** Error decoding Start Payload */
1970     silc_packet_free(ske->packet);
1971     ske->packet = NULL;
1972     ske->status = status;
1973     silc_fsm_next(fsm, silc_ske_st_responder_error);
1974     return SILC_FSM_CONTINUE;
1975   }
1976
1977   /* Get remote ID and set it to stream */
1978   if (ske->packet->src_id_len) {
1979     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1980                    ske->packet->src_id_type,
1981                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1982                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1983                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1984                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1985     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1986                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1987                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1988   }
1989
1990   /* Take a copy of the payload buffer for future use. It is used to
1991      compute the HASH value. */
1992   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1993   if (!ske->start_payload_copy) {
1994     silc_packet_free(ske->packet);
1995     ske->packet = NULL;
1996     ske->status = status;
1997     silc_fsm_next(fsm, silc_ske_st_responder_error);
1998     return SILC_FSM_CONTINUE;
1999   }
2000
2001   silc_packet_free(ske->packet);
2002   ske->packet = NULL;
2003
2004   /* Force the mutual authentication flag if we want to do it. */
2005   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2006     SILC_LOG_DEBUG(("Force mutual authentication"));
2007     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2008   }
2009
2010   /* Force PFS flag if we require it */
2011   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2012     SILC_LOG_DEBUG(("Force PFS"));
2013     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2014   }
2015
2016   /* Disable IV Included flag if requested */
2017   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2018       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2019     SILC_LOG_DEBUG(("We do not support IV Included flag"));
2020     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2021   }
2022
2023   /* Check and select security properties */
2024   status = silc_ske_select_security_properties(ske, remote_payload,
2025                                                &ske->prop);
2026   if (status != SILC_SKE_STATUS_OK) {
2027     /** Error selecting proposal */
2028     silc_ske_payload_start_free(remote_payload);
2029     ske->status = status;
2030     silc_fsm_next(fsm, silc_ske_st_responder_error);
2031     return SILC_FSM_CONTINUE;
2032   }
2033
2034   silc_ske_payload_start_free(remote_payload);
2035
2036   /* Encode our reply payload to send the selected security properties */
2037   status = silc_ske_payload_start_encode(ske, ske->start_payload,
2038                                          &packet_buf);
2039   if (status != SILC_SKE_STATUS_OK)
2040     goto err;
2041
2042   /* Send the packet. */
2043   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2044                             silc_buffer_data(packet_buf),
2045                             silc_buffer_len(packet_buf)))
2046     goto err;
2047
2048   silc_buffer_free(packet_buf);
2049
2050   /** Waiting initiator's KE payload */
2051   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2052   return SILC_FSM_WAIT;
2053
2054  err:
2055   if (ske->prop->group)
2056     silc_ske_group_free(ske->prop->group);
2057   if (ske->prop->cipher)
2058     silc_cipher_free(ske->prop->cipher);
2059   if (ske->prop->hash)
2060     silc_hash_free(ske->prop->hash);
2061   if (ske->prop->hmac)
2062     silc_hmac_free(ske->prop->hmac);
2063   silc_free(ske->prop);
2064   ske->prop = NULL;
2065
2066   if (status == SILC_SKE_STATUS_OK)
2067     status = SILC_SKE_STATUS_ERROR;
2068
2069   /** Error */
2070   ske->status = status;
2071   silc_fsm_next(fsm, silc_ske_st_responder_error);
2072   return SILC_FSM_CONTINUE;
2073 }
2074
2075 /* Phase-2.  Decode initiator's KE payload */
2076
2077 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2078 {
2079   SilcSKE ske = fsm_context;
2080   SilcSKEStatus status;
2081   SilcSKEKEPayload recv_payload;
2082   SilcBuffer packet_buf = &ske->packet->buffer;
2083
2084   SILC_LOG_DEBUG(("Start"));
2085
2086   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2087     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2088     silc_ske_install_retransmission(ske);
2089     silc_packet_free(ske->packet);
2090     ske->packet = NULL;
2091     return SILC_FSM_WAIT;
2092   }
2093
2094   /* Decode Key Exchange Payload */
2095   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2096   if (status != SILC_SKE_STATUS_OK) {
2097     /** Error decoding KE payload */
2098     silc_packet_free(ske->packet);
2099     ske->packet = NULL;
2100     ske->status = status;
2101     silc_fsm_next(fsm, silc_ske_st_responder_error);
2102     return SILC_FSM_CONTINUE;
2103   }
2104
2105   ske->ke1_payload = recv_payload;
2106
2107   silc_packet_free(ske->packet);
2108   ske->packet = NULL;
2109
2110   /* Verify public key, except in rekey, when it is not sent */
2111   if (!ske->rekey) {
2112     if (!recv_payload->pk_data) {
2113       /** Public key not provided */
2114       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2115                       "certificate), even though we require it"));
2116       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2117       silc_fsm_next(fsm, silc_ske_st_responder_error);
2118       return SILC_FSM_CONTINUE;
2119     }
2120
2121     /* Decode the remote's public key */
2122     if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2123                                     recv_payload->pk_data,
2124                                     recv_payload->pk_len,
2125                                     &ske->prop->public_key)) {
2126       /** Error decoding public key */
2127       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2128       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2129       silc_fsm_next(fsm, silc_ske_st_responder_error);
2130       return SILC_FSM_CONTINUE;
2131     }
2132
2133     SILC_LOG_DEBUG(("Verifying public key"));
2134
2135     /** Waiting public key verification */
2136     silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2137
2138     /* If repository is provided, verify the key from there. */
2139     if (ske->repository) {
2140       SilcSKRFind find;
2141
2142       find = silc_skr_find_alloc();
2143       if (!find) {
2144         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2145         silc_fsm_next(fsm, silc_ske_st_responder_error);
2146         return SILC_FSM_CONTINUE;
2147       }
2148       silc_skr_find_set_pkcs_type(find,
2149                                   silc_pkcs_get_type(ske->prop->public_key));
2150       silc_skr_find_set_public_key(find, ske->prop->public_key);
2151       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2152
2153       /* Find key from repository */
2154       SILC_FSM_CALL(silc_skr_find(ske->repository,
2155                                   silc_fsm_get_schedule(fsm), find,
2156                                   silc_ske_skr_callback, ske));
2157     } else {
2158       /* Verify from application */
2159       if (ske->callbacks->verify_key)
2160         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2161                                                  ske->callbacks->context,
2162                                                  silc_ske_pk_verified, NULL));
2163     }
2164   }
2165
2166   /** Generate KE2 payload */
2167   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2168   return SILC_FSM_CONTINUE;
2169 }
2170
2171 /* Phase-4. Generate KE2 payload */
2172
2173 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2174 {
2175   SilcSKE ske = fsm_context;
2176   SilcSKEStatus status;
2177   SilcSKEKEPayload recv_payload, send_payload = NULL;
2178   SilcMPInt *x = NULL, *KEY;
2179
2180   if (ske->aborted) {
2181     /** Aborted */
2182     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2183     return SILC_FSM_CONTINUE;
2184   }
2185
2186   /* Check result of public key verification */
2187   if (ske->status != SILC_SKE_STATUS_OK) {
2188     /** Public key not verified */
2189     SILC_LOG_DEBUG(("Public key verification failed"));
2190     goto err;
2191   }
2192
2193   recv_payload = ske->ke1_payload;
2194
2195   /* The public key verification was performed only if the Mutual
2196      Authentication flag is set. */
2197   if (ske->start_payload &&
2198       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2199     unsigned char hash[SILC_HASH_MAXLEN];
2200     SilcUInt32 hash_len;
2201
2202     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2203
2204     /* Compute the hash value */
2205     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2206     if (status != SILC_SKE_STATUS_OK) {
2207       /** Error computing hash */
2208       SILC_LOG_DEBUG(("Error computing hash"));
2209       ske->status = status;
2210       goto err;
2211     }
2212
2213     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2214
2215     /* Verify signature */
2216     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2217                           recv_payload->sign_len, hash, hash_len, NULL)) {
2218       /** Incorrect signature */
2219       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2220       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2221       goto err;
2222     }
2223
2224     SILC_LOG_DEBUG(("Signature is Ok"));
2225
2226     memset(hash, 'F', hash_len);
2227   }
2228
2229   /* Create the random number x, 1 < x < q. */
2230   x = silc_calloc(1, sizeof(*x));
2231   if (!x) {
2232     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2233     goto err;
2234   }
2235   silc_mp_init(x);
2236   status =
2237     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2238                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2239                         x);
2240   if (status != SILC_SKE_STATUS_OK) {
2241     /** Error generating random number */
2242     ske->status = status;
2243     goto err;
2244   }
2245
2246   /* Save the results for later processing */
2247   send_payload = silc_calloc(1, sizeof(*send_payload));
2248   if (!send_payload) {
2249     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2250     goto err;
2251   }
2252   ske->x = x;
2253   ske->ke2_payload = send_payload;
2254
2255   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2256
2257   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2258   silc_mp_init(&send_payload->x);
2259   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2260                   &ske->prop->group->group);
2261
2262   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2263
2264   /* Compute the shared secret key */
2265   KEY = silc_calloc(1, sizeof(*KEY));
2266   if (!KEY) {
2267     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2268     goto err;
2269   }
2270   silc_mp_init(KEY);
2271   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2272                   &ske->prop->group->group);
2273   ske->KEY = KEY;
2274
2275   /** Send KE2 payload */
2276   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2277   return SILC_FSM_CONTINUE;
2278
2279  err:
2280   silc_mp_uninit(x);
2281   silc_free(x);
2282   ske->x = NULL;
2283   silc_free(send_payload);
2284   ske->ke2_payload = NULL;
2285
2286   silc_fsm_next(fsm, silc_ske_st_responder_error);
2287   return SILC_FSM_CONTINUE;
2288 }
2289
2290 /* Phase-5.  Send KE2 payload */
2291
2292 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2293 {
2294   SilcSKE ske = fsm_context;
2295   SilcSKEStatus status;
2296   SilcBuffer payload_buf;
2297   unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1], *pk;
2298   SilcUInt32 hash_len, sign_len, pk_len;
2299
2300   SILC_LOG_DEBUG(("Start"));
2301
2302   if (ske->public_key && ske->private_key) {
2303     SILC_LOG_DEBUG(("Getting public key"));
2304
2305     /* Get the public key */
2306     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2307     if (!pk) {
2308       /** Error encoding public key */
2309       ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2310       silc_fsm_next(fsm, silc_ske_st_responder_error);
2311       return SILC_FSM_CONTINUE;
2312     }
2313     ske->ke2_payload->pk_data = pk;
2314     ske->ke2_payload->pk_len = pk_len;
2315   }
2316
2317   SILC_LOG_DEBUG(("Computing HASH value"));
2318
2319   /* Compute the hash value */
2320   memset(hash, 0, sizeof(hash));
2321   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2322   if (status != SILC_SKE_STATUS_OK) {
2323     /** Error computing hash */
2324     ske->status = status;
2325     silc_fsm_next(fsm, silc_ske_st_responder_error);
2326     return SILC_FSM_CONTINUE;
2327   }
2328   ske->hash = silc_memdup(hash, hash_len);
2329   if (!ske->hash) {
2330     /** Error computing hash */
2331     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2332     silc_fsm_next(fsm, silc_ske_st_responder_error);
2333     return SILC_FSM_CONTINUE;
2334   }
2335   ske->hash_len = hash_len;
2336
2337   if (ske->public_key && ske->private_key) {
2338     SILC_LOG_DEBUG(("Signing HASH value"));
2339
2340     /* Sign the hash value */
2341     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2342                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2343       /** Error computing signature */
2344       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2345       silc_fsm_next(fsm, silc_ske_st_responder_error);
2346       return SILC_FSM_CONTINUE;
2347     }
2348     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2349     if (!ske->ke2_payload->sign_data) {
2350       /** Error computing hash */
2351       ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2352       silc_fsm_next(fsm, silc_ske_st_responder_error);
2353       return SILC_FSM_CONTINUE;
2354     }
2355     ske->ke2_payload->sign_len = sign_len;
2356     memset(sign, 0, sizeof(sign));
2357   }
2358   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2359
2360   /* Encode the Key Exchange Payload */
2361   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2362                                       &payload_buf);
2363   if (status != SILC_SKE_STATUS_OK) {
2364     /** Error encoding KE payload */
2365     ske->status = status;
2366     silc_fsm_next(fsm, silc_ske_st_responder_error);
2367     return SILC_FSM_CONTINUE;
2368   }
2369
2370   /* Send the packet. */
2371   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2372                             payload_buf->data, silc_buffer_len(payload_buf))) {
2373     SILC_LOG_DEBUG(("Error sending packet"));
2374     ske->status = SILC_SKE_STATUS_ERROR;
2375     silc_fsm_next(fsm, silc_ske_st_responder_error);
2376     return SILC_FSM_CONTINUE;
2377   }
2378
2379   silc_buffer_free(payload_buf);
2380
2381   /* In case we are doing rekey move to finish it. */
2382   if (ske->rekey) {
2383     /** Finish rekey */
2384     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2385     return SILC_FSM_CONTINUE;
2386   }
2387
2388   /** Waiting completion */
2389   silc_fsm_next(fsm, silc_ske_st_responder_end);
2390   return SILC_FSM_WAIT;
2391 }
2392
2393 /* Protocol completed */
2394
2395 SILC_FSM_STATE(silc_ske_st_responder_end)
2396 {
2397   SilcSKE ske = fsm_context;
2398   unsigned char tmp[4];
2399   SilcUInt32 hash_len, key_len, block_len;
2400
2401   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2402     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2403     silc_ske_install_retransmission(ske);
2404     silc_packet_free(ske->packet);
2405     ske->packet = NULL;
2406     return SILC_FSM_WAIT;
2407   }
2408   silc_packet_free(ske->packet);
2409   ske->packet = NULL;
2410
2411   /* Process key material */
2412   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2413   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2414   hash_len = silc_hash_len(ske->prop->hash);
2415   ske->keymat = silc_ske_process_key_material(ske, block_len,
2416                                               key_len, hash_len,
2417                                               &ske->rekey);
2418   if (!ske->keymat) {
2419     /** Error processing key material */
2420     ske->status = SILC_SKE_STATUS_ERROR;
2421     silc_fsm_next(fsm, silc_ske_st_responder_error);
2422     return SILC_FSM_CONTINUE;
2423   }
2424
2425   /* Send SUCCESS packet */
2426   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2427   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2428
2429   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2430   silc_schedule_task_del_by_context(ske->schedule, ske);
2431
2432   /* Call completion */
2433   silc_ske_completion(ske);
2434
2435   return SILC_FSM_FINISH;
2436 }
2437
2438 /* Aborted by application */
2439
2440 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2441 {
2442   SilcSKE ske = fsm_context;
2443   unsigned char tmp[4];
2444
2445   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2446
2447   /* Send FAILURE packet */
2448   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2449   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2450
2451   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2452   silc_schedule_task_del_by_context(ske->schedule, ske);
2453
2454   /* Call completion */
2455   silc_ske_completion(ske);
2456
2457   return SILC_FSM_FINISH;
2458 }
2459
2460 /* Failure received from remote */
2461
2462 SILC_FSM_STATE(silc_ske_st_responder_failure)
2463 {
2464   SilcSKE ske = fsm_context;
2465   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2466
2467   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2468
2469   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2470     SILC_GET32_MSB(error, ske->packet->buffer.data);
2471     silc_packet_free(ske->packet);
2472     ske->packet = NULL;
2473   }
2474   ske->status = error;
2475   if (ske->status == SILC_SKE_STATUS_OK)
2476     ske->status = SILC_SKE_STATUS_ERROR;
2477
2478   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2479   silc_schedule_task_del_by_context(ske->schedule, ske);
2480
2481   /* Call completion */
2482   silc_ske_completion(ske);
2483
2484   return SILC_FSM_FINISH;
2485 }
2486
2487 /* Error occurred */
2488
2489 SILC_FSM_STATE(silc_ske_st_responder_error)
2490 {
2491   SilcSKE ske = fsm_context;
2492   unsigned char tmp[4];
2493
2494   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2495                   ske->status, silc_ske_map_status(ske->status)));
2496
2497   /* Send FAILURE packet */
2498   if (ske->status == SILC_SKE_STATUS_OUT_OF_MEMORY)
2499     ske->status = SILC_SKE_STATUS_ERROR;
2500   else if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2501     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2502   SILC_PUT32_MSB(ske->status, tmp);
2503   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2504
2505   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2506   silc_schedule_task_del_by_context(ske->schedule, ske);
2507
2508   /* Call completion */
2509   silc_ske_completion(ske);
2510
2511   return SILC_FSM_FINISH;
2512 }
2513
2514 /* Starts the protocol as responder. */
2515
2516 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2517                                       SilcPacketStream stream,
2518                                       SilcSKEParams params)
2519 {
2520   SILC_LOG_DEBUG(("Start SKE as responder"));
2521
2522   if (!ske || !stream || !params || !params->version)
2523     return NULL;
2524
2525   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2526     return NULL;
2527
2528   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2529     return NULL;
2530
2531   ske->responder = TRUE;
2532   ske->flags = params->flags;
2533   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2534   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2535     ske->session_port = params->session_port;
2536   ske->version = params->version;
2537   if (!ske->version)
2538     return NULL;
2539   ++ske->refcnt;
2540
2541   /* Link to packet stream to get key exchange packets */
2542   ske->stream = stream;
2543   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2544                           SILC_PACKET_KEY_EXCHANGE,
2545                           SILC_PACKET_KEY_EXCHANGE_1,
2546                           SILC_PACKET_SUCCESS,
2547                           SILC_PACKET_FAILURE, -1);
2548
2549   /* Start SKE as responder */
2550   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2551
2552   return &ske->op;
2553 }
2554
2555 /***************************** Initiator Rekey ******************************/
2556
2557 /* Start rekey */
2558
2559 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2560 {
2561   SilcSKE ske = fsm_context;
2562   SilcStatus status;
2563
2564   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2565
2566   if (ske->aborted) {
2567     /** Aborted */
2568     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2569     return SILC_FSM_CONTINUE;
2570   }
2571
2572   /* Add rekey exchange timeout */
2573   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2574                                  ske, 30, 0);
2575
2576   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2577   if (!ske->prop) {
2578     /** No memory */
2579     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2580     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2581     return SILC_FSM_CONTINUE;
2582   }
2583
2584   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2585     /** Cannot allocate hash */
2586     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2587     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2588     return SILC_FSM_CONTINUE;
2589   }
2590
2591   /* Send REKEY packet to start rekey protocol */
2592   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2593     /** Error sending packet */
2594     SILC_LOG_DEBUG(("Error sending packet"));
2595     ske->status = SILC_SKE_STATUS_ERROR;
2596     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2597     return SILC_FSM_CONTINUE;
2598   }
2599
2600   /* If doing rekey without PFS, move directly to the end of the protocol. */
2601   if (!ske->rekey->pfs) {
2602     /** Rekey without PFS */
2603     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2604     return SILC_FSM_CONTINUE;
2605   }
2606
2607   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2608                                         &ske->prop->group);
2609   if (status != SILC_SKE_STATUS_OK) {
2610     /** Unknown group */
2611     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2612     return SILC_FSM_CONTINUE;
2613   }
2614
2615   /** Rekey with PFS */
2616   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2617   return SILC_FSM_CONTINUE;
2618 }
2619
2620 /* Sends REKEY_DONE packet to finish the protocol. */
2621
2622 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2623 {
2624   SilcSKE ske = fsm_context;
2625   SilcCipher send_key;
2626   SilcHmac hmac_send;
2627   SilcHash hash;
2628   SilcUInt32 key_len, block_len, hash_len, x_len;
2629   unsigned char *pfsbuf;
2630
2631   SILC_LOG_DEBUG(("Start"));
2632
2633   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2634   key_len = silc_cipher_get_key_len(send_key);
2635   block_len = silc_cipher_get_block_len(send_key);
2636   hash = ske->prop->hash;
2637   hash_len = silc_hash_len(hash);
2638
2639   /* Process key material */
2640   if (ske->rekey->pfs) {
2641     /* PFS */
2642     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2643     if (!pfsbuf) {
2644       SILC_LOG_ERROR(("Error processing key material"));
2645       silc_fsm_next(fsm, silc_ske_st_initiator_error);
2646       return SILC_FSM_CONTINUE;
2647     }
2648     ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2649                                                      block_len, key_len,
2650                                                      hash_len, hash);
2651     memset(pfsbuf, 0, x_len);
2652     silc_free(pfsbuf);
2653   } else {
2654     /* No PFS */
2655     ske->keymat =
2656       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2657                                          ske->rekey->enc_key_len / 8,
2658                                          block_len, key_len,
2659                                          hash_len, hash);
2660   }
2661
2662   if (!ske->keymat) {
2663     SILC_LOG_ERROR(("Error processing key material"));
2664     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2665     return SILC_FSM_CONTINUE;
2666   }
2667
2668   ske->prop->cipher = send_key;
2669   ske->prop->hmac = hmac_send;
2670
2671   /* Get sending keys */
2672   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2673                          &hmac_send, NULL, NULL)) {
2674     /** Cannot get keys */
2675     ske->status = SILC_SKE_STATUS_ERROR;
2676     ske->prop->cipher = NULL;
2677     ske->prop->hmac = NULL;
2678     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2679     return SILC_FSM_CONTINUE;
2680   }
2681
2682   ske->prop->cipher = NULL;
2683   ske->prop->hmac = NULL;
2684
2685   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2686      packet sent after this call will be protected with the new keys. */
2687   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2688                             TRUE)) {
2689     /** Cannot set keys */
2690     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2691     ske->status = SILC_SKE_STATUS_ERROR;
2692     silc_cipher_free(send_key);
2693     silc_hmac_free(hmac_send);
2694     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2695     return SILC_FSM_CONTINUE;
2696   }
2697
2698   /** Wait for REKEY_DONE */
2699   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2700   return SILC_FSM_WAIT;
2701 }
2702
2703 /* Rekey protocol end */
2704
2705 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2706 {
2707   SilcSKE ske = fsm_context;
2708   SilcCipher receive_key;
2709   SilcHmac hmac_receive;
2710   SilcSKERekeyMaterial rekey;
2711
2712   SILC_LOG_DEBUG(("Start"));
2713
2714   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2715     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2716     silc_packet_free(ske->packet);
2717     ske->packet = NULL;
2718     return SILC_FSM_WAIT;
2719   }
2720
2721   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2722   ske->prop->cipher = receive_key;
2723   ske->prop->hmac = hmac_receive;
2724
2725   /* Get receiving keys */
2726   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2727                          NULL, &hmac_receive, NULL)) {
2728     /** Cannot get keys */
2729     ske->status = SILC_SKE_STATUS_ERROR;
2730     ske->prop->cipher = NULL;
2731     ske->prop->hmac = NULL;
2732     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2733     return SILC_FSM_CONTINUE;
2734   }
2735
2736   /* Set new receiving keys into use.  All packets received after this will
2737      be decrypted with the new keys. */
2738   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2739                             hmac_receive, FALSE)) {
2740     /** Cannot set keys */
2741     SILC_LOG_DEBUG(("Cannot set new keys"));
2742     ske->status = SILC_SKE_STATUS_ERROR;
2743     silc_cipher_free(receive_key);
2744     silc_hmac_free(hmac_receive);
2745     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2746     return SILC_FSM_CONTINUE;
2747   }
2748
2749   SILC_LOG_DEBUG(("Rekey completed successfully"));
2750
2751   /* Generate new rekey material */
2752   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2753   if (!rekey) {
2754     /** No memory */
2755     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2756     ske->prop->cipher = NULL;
2757     ske->prop->hmac = NULL;
2758     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2759     return SILC_FSM_CONTINUE;
2760   }
2761   rekey->pfs = ske->rekey->pfs;
2762   ske->rekey = rekey;
2763
2764   ske->prop->cipher = NULL;
2765   ske->prop->hmac = NULL;
2766   silc_packet_free(ske->packet);
2767   ske->packet = NULL;
2768   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2769   silc_schedule_task_del_by_context(ske->schedule, ske);
2770
2771   /* Call completion */
2772   silc_ske_completion(ske);
2773
2774   return SILC_FSM_FINISH;
2775 }
2776
2777 /* Starts rekey protocol as initiator */
2778
2779 SilcAsyncOperation
2780 silc_ske_rekey_initiator(SilcSKE ske,
2781                          SilcPacketStream stream,
2782                          SilcSKERekeyMaterial rekey)
2783 {
2784   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2785
2786   if (!ske || !stream || !rekey) {
2787     SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2788     SILC_ASSERT(rekey);
2789     return NULL;
2790   }
2791
2792   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2793     return NULL;
2794
2795   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2796     return NULL;
2797
2798   ske->rekey = rekey;
2799   ske->responder = FALSE;
2800   ske->rekeying = TRUE;
2801   ++ske->refcnt;
2802
2803   /* Link to packet stream to get key exchange packets */
2804   ske->stream = stream;
2805   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2806                           SILC_PACKET_REKEY,
2807                           SILC_PACKET_REKEY_DONE,
2808                           SILC_PACKET_KEY_EXCHANGE_2,
2809                           SILC_PACKET_SUCCESS,
2810                           SILC_PACKET_FAILURE, -1);
2811
2812   /* Start SKE rekey as initiator */
2813   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2814
2815   return &ske->op;
2816 }
2817
2818 /***************************** Responder Rekey ******************************/
2819
2820 /* Wait for initiator's packet */
2821
2822 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2823 {
2824   SilcSKE ske = fsm_context;
2825
2826   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2827
2828   if (ske->aborted) {
2829     /** Aborted */
2830     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2831     return SILC_FSM_CONTINUE;
2832   }
2833
2834   /* Add rekey exchange timeout */
2835   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2836                                  ske, 30, 0);
2837
2838   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2839
2840   /* If REKEY packet already received process it directly */
2841   if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2842     return SILC_FSM_CONTINUE;
2843
2844   /* Wait for REKEY */
2845   return SILC_FSM_WAIT;
2846 }
2847
2848 /* Process initiator's REKEY packet */
2849
2850 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2851 {
2852   SilcSKE ske = fsm_context;
2853   SilcSKEStatus status;
2854
2855   SILC_LOG_DEBUG(("Start"));
2856
2857   if (ske->packet->type != SILC_PACKET_REKEY) {
2858     ske->status = SILC_SKE_STATUS_ERROR;
2859     silc_packet_free(ske->packet);
2860     ske->packet = NULL;
2861     silc_fsm_next(fsm, silc_ske_st_responder_error);
2862     return SILC_FSM_CONTINUE;
2863   }
2864
2865   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2866   if (!ske->prop) {
2867     /** No memory */
2868     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2869     silc_fsm_next(fsm, silc_ske_st_responder_error);
2870     return SILC_FSM_CONTINUE;
2871   }
2872
2873   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2874     /** Cannot allocate hash */
2875     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2876     silc_fsm_next(fsm, silc_ske_st_responder_error);
2877     return SILC_FSM_CONTINUE;
2878   }
2879
2880   /* If doing rekey without PFS, move directly to the end of the protocol. */
2881   if (!ske->rekey->pfs) {
2882     /** Rekey without PFS */
2883     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2884     return SILC_FSM_CONTINUE;
2885   }
2886
2887   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2888                                         &ske->prop->group);
2889   if (status != SILC_SKE_STATUS_OK) {
2890     /** Unknown group */
2891     silc_fsm_next(fsm, silc_ske_st_responder_error);
2892     return SILC_FSM_CONTINUE;
2893   }
2894
2895   /** Rekey with PFS */
2896   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2897   return SILC_FSM_WAIT;
2898 }
2899
2900 /* Sends REKEY_DONE packet to finish the protocol. */
2901
2902 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2903 {
2904   SilcSKE ske = fsm_context;
2905   SilcCipher send_key;
2906   SilcHmac hmac_send;
2907   SilcHash hash;
2908   SilcUInt32 key_len, block_len, hash_len, x_len;
2909   unsigned char *pfsbuf;
2910
2911   SILC_LOG_DEBUG(("Start"));
2912
2913   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2914   key_len = silc_cipher_get_key_len(send_key);
2915   block_len = silc_cipher_get_block_len(send_key);
2916   hash = ske->prop->hash;
2917   hash_len = silc_hash_len(hash);
2918
2919   /* Process key material */
2920   if (ske->rekey->pfs) {
2921     /* PFS */
2922     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2923     if (!pfsbuf) {
2924       SILC_LOG_ERROR(("Error processing key material"));
2925       silc_fsm_next(fsm, silc_ske_st_responder_error);
2926       return SILC_FSM_CONTINUE;
2927     }
2928     ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2929                                                      block_len, key_len,
2930                                                      hash_len, hash);
2931     memset(pfsbuf, 0, x_len);
2932     silc_free(pfsbuf);
2933   } else {
2934     /* No PFS */
2935     ske->keymat =
2936       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2937                                          ske->rekey->enc_key_len / 8,
2938                                          block_len, key_len,
2939                                          hash_len, hash);
2940   }
2941
2942   if (!ske->keymat) {
2943     SILC_LOG_ERROR(("Error processing key material"));
2944     silc_fsm_next(fsm, silc_ske_st_responder_error);
2945     return SILC_FSM_CONTINUE;
2946   }
2947
2948   ske->prop->cipher = send_key;
2949   ske->prop->hmac = hmac_send;
2950
2951   /* Get sending keys */
2952   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2953                          &hmac_send, NULL, NULL)) {
2954     /** Cannot get keys */
2955     ske->status = SILC_SKE_STATUS_ERROR;
2956     ske->prop->cipher = NULL;
2957     ske->prop->hmac = NULL;
2958     silc_fsm_next(fsm, silc_ske_st_responder_error);
2959     return SILC_FSM_CONTINUE;
2960   }
2961
2962   ske->prop->cipher = NULL;
2963   ske->prop->hmac = NULL;
2964
2965   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2966      packet sent after this call will be protected with the new keys. */
2967   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2968                             TRUE)) {
2969     /** Cannot set keys */
2970     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2971     ske->status = SILC_SKE_STATUS_ERROR;
2972     silc_cipher_free(send_key);
2973     silc_hmac_free(hmac_send);
2974     silc_fsm_next(fsm, silc_ske_st_responder_error);
2975     return SILC_FSM_CONTINUE;
2976   }
2977
2978   /** Wait for REKEY_DONE */
2979   silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2980   return SILC_FSM_WAIT;
2981 }
2982
2983 /* Rekey protocol end */
2984
2985 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2986 {
2987   SilcSKE ske = fsm_context;
2988   SilcCipher receive_key;
2989   SilcHmac hmac_receive;
2990   SilcSKERekeyMaterial rekey;
2991
2992   SILC_LOG_DEBUG(("Start"));
2993
2994   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2995     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2996     silc_packet_free(ske->packet);
2997     ske->packet = NULL;
2998     return SILC_FSM_WAIT;
2999   }
3000
3001   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
3002   ske->prop->cipher = receive_key;
3003   ske->prop->hmac = hmac_receive;
3004
3005   /* Get receiving keys */
3006   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3007                          NULL, &hmac_receive, NULL)) {
3008     /** Cannot get keys */
3009     ske->status = SILC_SKE_STATUS_ERROR;
3010     ske->prop->cipher = NULL;
3011     ske->prop->hmac = NULL;
3012     silc_fsm_next(fsm, silc_ske_st_responder_error);
3013     return SILC_FSM_CONTINUE;
3014   }
3015
3016   /* Set new receiving keys into use.  All packets received after this will
3017      be decrypted with the new keys. */
3018   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3019                             hmac_receive, FALSE)) {
3020     /** Cannot set keys */
3021     SILC_LOG_DEBUG(("Cannot set new keys"));
3022     ske->status = SILC_SKE_STATUS_ERROR;
3023     ske->prop->cipher = NULL;
3024     ske->prop->hmac = NULL;
3025     silc_cipher_free(receive_key);
3026     silc_hmac_free(hmac_receive);
3027     silc_fsm_next(fsm, silc_ske_st_responder_error);
3028     return SILC_FSM_CONTINUE;
3029   }
3030
3031   SILC_LOG_DEBUG(("Rekey completed successfully"));
3032
3033   /* Generate new rekey material */
3034   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3035   if (!rekey) {
3036     /** No memory */
3037     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3038     ske->prop->cipher = NULL;
3039     ske->prop->hmac = NULL;
3040     silc_fsm_next(fsm, silc_ske_st_responder_error);
3041     return SILC_FSM_CONTINUE;
3042   }
3043   rekey->pfs = ske->rekey->pfs;
3044   ske->rekey = rekey;
3045
3046   ske->prop->cipher = NULL;
3047   ske->prop->hmac = NULL;
3048   silc_packet_free(ske->packet);
3049   ske->packet = NULL;
3050   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3051   silc_schedule_task_del_by_context(ske->schedule, ske);
3052
3053   /* Call completion */
3054   silc_ske_completion(ske);
3055
3056   return SILC_FSM_FINISH;
3057 }
3058
3059 /* Starts rekey protocol as responder */
3060
3061 SilcAsyncOperation
3062 silc_ske_rekey_responder(SilcSKE ske,
3063                          SilcPacketStream stream,
3064                          SilcSKERekeyMaterial rekey,
3065                          SilcPacket packet)
3066 {
3067   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3068
3069   if (!ske || !stream || !rekey)
3070     return NULL;
3071
3072   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3073     return NULL;
3074
3075   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3076     return NULL;
3077
3078   ske->rekey = rekey;
3079   ske->responder = TRUE;
3080   ske->rekeying = TRUE;
3081   ske->packet = packet;
3082   ++ske->refcnt;
3083
3084   /* Link to packet stream to get key exchange packets */
3085   ske->stream = stream;
3086   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3087                           SILC_PACKET_REKEY,
3088                           SILC_PACKET_REKEY_DONE,
3089                           SILC_PACKET_KEY_EXCHANGE_1,
3090                           SILC_PACKET_SUCCESS,
3091                           SILC_PACKET_FAILURE, -1);
3092
3093   /* Start SKE rekey as responder */
3094   silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3095
3096   return &ske->op;
3097 }
3098
3099 /* Processes the provided key material `data' as the SILC protocol
3100    specification defines. */
3101
3102 SilcSKEKeyMaterial
3103 silc_ske_process_key_material_data(unsigned char *data,
3104                                    SilcUInt32 data_len,
3105                                    SilcUInt32 req_iv_len,
3106                                    SilcUInt32 req_enc_key_len,
3107                                    SilcUInt32 req_hmac_key_len,
3108                                    SilcHash hash)
3109 {
3110   SilcBuffer buf;
3111   unsigned char hashd[SILC_HASH_MAXLEN];
3112   SilcUInt32 hash_len = req_hmac_key_len;
3113   SilcUInt32 enc_key_len = req_enc_key_len / 8;
3114   SilcSKEKeyMaterial key;
3115
3116   SILC_LOG_DEBUG(("Start"));
3117
3118   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3119     return NULL;
3120
3121   key = silc_calloc(1, sizeof(*key));
3122   if (!key)
3123     return NULL;
3124
3125   buf = silc_buffer_alloc_size(1 + data_len);
3126   if (!buf)
3127     return NULL;
3128   silc_buffer_format(buf,
3129                      SILC_STR_UI_CHAR(0),
3130                      SILC_STR_DATA(data, data_len),
3131                      SILC_STR_END);
3132
3133   /* Take IVs */
3134   memset(hashd, 0, sizeof(hashd));
3135   buf->data[0] = 0;
3136   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3137   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3138   if (!key->send_iv) {
3139     silc_buffer_clear(buf);
3140     silc_buffer_free(buf);
3141     silc_free(key);
3142     return NULL;
3143   }
3144   memcpy(key->send_iv, hashd, req_iv_len);
3145   memset(hashd, 0, sizeof(hashd));
3146   buf->data[0] = 1;
3147   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3148   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3149   if (!key->receive_iv) {
3150     silc_buffer_clear(buf);
3151     silc_buffer_free(buf);
3152     silc_free(key);
3153     return NULL;
3154   }
3155   memcpy(key->receive_iv, hashd, req_iv_len);
3156   key->iv_len = req_iv_len;
3157
3158   /* Take the encryption keys. If requested key size is more than
3159      the size of hash length we will distribute more key material
3160      as protocol defines. */
3161   buf->data[0] = 2;
3162   if (enc_key_len > hash_len) {
3163     SilcBuffer dist;
3164     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3165         k3[SILC_HASH_MAXLEN];
3166     unsigned char *dtmp;
3167
3168     /* XXX */
3169     if (enc_key_len > (3 * hash_len))
3170       return NULL;
3171
3172     /* Take first round */
3173     memset(k1, 0, sizeof(k1));
3174     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3175
3176     /* Take second round */
3177     dist = silc_buffer_alloc_size(data_len + hash_len);
3178     if (!dist)
3179       return NULL;
3180     silc_buffer_format(dist,
3181                        SILC_STR_DATA(data, data_len),
3182                        SILC_STR_DATA(k1, hash_len),
3183                        SILC_STR_END);
3184     memset(k2, 0, sizeof(k2));
3185     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3186
3187     /* Take third round */
3188     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3189     silc_buffer_pull_tail(dist, hash_len);
3190     silc_buffer_pull(dist, data_len + hash_len);
3191     silc_buffer_format(dist,
3192                        SILC_STR_DATA(k2, hash_len),
3193                        SILC_STR_END);
3194     silc_buffer_push(dist, data_len + hash_len);
3195     memset(k3, 0, sizeof(k3));
3196     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3197
3198     /* Then, save the keys */
3199     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3200     if (!dtmp) {
3201       silc_buffer_clear(buf);
3202       silc_buffer_free(buf);
3203       silc_free(key);
3204       return NULL;
3205     }
3206     memcpy(dtmp, k1, hash_len);
3207     memcpy(dtmp + hash_len, k2, hash_len);
3208     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3209
3210     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3211     if (!key->send_enc_key) {
3212       silc_buffer_clear(buf);
3213       silc_buffer_free(buf);
3214       silc_free(key);
3215       silc_free(dtmp);
3216       return NULL;
3217     }
3218     memcpy(key->send_enc_key, dtmp, enc_key_len);
3219     key->enc_key_len = req_enc_key_len;
3220
3221     memset(dtmp, 0, (3 * hash_len));
3222     memset(k1, 0, sizeof(k1));
3223     memset(k2, 0, sizeof(k2));
3224     memset(k3, 0, sizeof(k3));
3225     silc_free(dtmp);
3226     silc_buffer_clear(dist);
3227     silc_buffer_free(dist);
3228   } else {
3229     /* Take normal hash as key */
3230     memset(hashd, 0, sizeof(hashd));
3231     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3232     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3233     if (!key->send_enc_key) {
3234       silc_buffer_clear(buf);
3235       silc_buffer_free(buf);
3236       silc_free(key);
3237       return NULL;
3238     }
3239     memcpy(key->send_enc_key, hashd, enc_key_len);
3240     key->enc_key_len = req_enc_key_len;
3241   }
3242
3243   buf->data[0] = 3;
3244   if (enc_key_len > hash_len) {
3245     SilcBuffer dist;
3246     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3247         k3[SILC_HASH_MAXLEN];
3248     unsigned char *dtmp;
3249
3250     /* XXX */
3251     if (enc_key_len > (3 * hash_len))
3252       return NULL;
3253
3254     /* Take first round */
3255     memset(k1, 0, sizeof(k1));
3256     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3257
3258     /* Take second round */
3259     dist = silc_buffer_alloc_size(data_len + hash_len);
3260     if (!dist)
3261       return NULL;
3262     silc_buffer_format(dist,
3263                        SILC_STR_DATA(data, data_len),
3264                        SILC_STR_DATA(k1, hash_len),
3265                        SILC_STR_END);
3266     memset(k2, 0, sizeof(k2));
3267     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3268
3269     /* Take third round */
3270     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3271     silc_buffer_pull_tail(dist, hash_len);
3272     silc_buffer_pull(dist, data_len + hash_len);
3273     silc_buffer_format(dist,
3274                        SILC_STR_DATA(k2, hash_len),
3275                        SILC_STR_END);
3276     silc_buffer_push(dist, data_len + hash_len);
3277     memset(k3, 0, sizeof(k3));
3278     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3279
3280     /* Then, save the keys */
3281     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3282     if (!dtmp) {
3283       silc_buffer_clear(buf);
3284       silc_buffer_free(buf);
3285       silc_free(key);
3286       return NULL;
3287     }
3288     memcpy(dtmp, k1, hash_len);
3289     memcpy(dtmp + hash_len, k2, hash_len);
3290     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3291
3292     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3293     if (!key->receive_enc_key) {
3294       silc_buffer_clear(buf);
3295       silc_buffer_free(buf);
3296       silc_free(key);
3297       silc_free(dtmp);
3298       return NULL;
3299     }
3300     memcpy(key->receive_enc_key, dtmp, enc_key_len);
3301     key->enc_key_len = req_enc_key_len;
3302
3303     memset(dtmp, 0, (3 * hash_len));
3304     memset(k1, 0, sizeof(k1));
3305     memset(k2, 0, sizeof(k2));
3306     memset(k3, 0, sizeof(k3));
3307     silc_free(dtmp);
3308     silc_buffer_clear(dist);
3309     silc_buffer_free(dist);
3310   } else {
3311     /* Take normal hash as key */
3312     memset(hashd, 0, sizeof(hashd));
3313     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3314     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3315     if (!key->receive_enc_key) {
3316       silc_buffer_clear(buf);
3317       silc_buffer_free(buf);
3318       silc_free(key);
3319       return NULL;
3320     }
3321     memcpy(key->receive_enc_key, hashd, enc_key_len);
3322     key->enc_key_len = req_enc_key_len;
3323   }
3324
3325   /* Take HMAC keys */
3326   memset(hashd, 0, sizeof(hashd));
3327   buf->data[0] = 4;
3328   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3329   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3330   if (!key->send_hmac_key) {
3331     silc_buffer_clear(buf);
3332     silc_buffer_free(buf);
3333     silc_free(key);
3334     return NULL;
3335   }
3336   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3337   memset(hashd, 0, sizeof(hashd));
3338   buf->data[0] = 5;
3339   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3340   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3341   if (!key->receive_hmac_key) {
3342     silc_buffer_clear(buf);
3343     silc_buffer_free(buf);
3344     silc_free(key);
3345     return NULL;
3346   }
3347   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3348   key->hmac_key_len = req_hmac_key_len;
3349   memset(hashd, 0, sizeof(hashd));
3350
3351   silc_buffer_clear(buf);
3352   silc_buffer_free(buf);
3353
3354   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3355
3356   return key;
3357 }
3358
3359 /* Processes negotiated key material as protocol specifies. This returns
3360    the actual keys to be used in the SILC. */
3361
3362 SilcSKEKeyMaterial
3363 silc_ske_process_key_material(SilcSKE ske,
3364                               SilcUInt32 req_iv_len,
3365                               SilcUInt32 req_enc_key_len,
3366                               SilcUInt32 req_hmac_key_len,
3367                               SilcSKERekeyMaterial *rekey)
3368 {
3369   SilcBuffer buf;
3370   unsigned char *tmpbuf;
3371   SilcUInt32 klen;
3372   SilcSKEKeyMaterial key;
3373
3374   /* Encode KEY to binary data */
3375   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3376
3377   buf = silc_buffer_alloc_size(klen + ske->hash_len);
3378   if (!buf)
3379     return NULL;
3380   silc_buffer_format(buf,
3381                      SILC_STR_DATA(tmpbuf, klen),
3382                      SILC_STR_DATA(ske->hash, ske->hash_len),
3383                      SILC_STR_END);
3384
3385   /* Process the key material */
3386   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3387                                            req_iv_len, req_enc_key_len,
3388                                            req_hmac_key_len,
3389                                            ske->prop->hash);
3390
3391   memset(tmpbuf, 0, klen);
3392   silc_free(tmpbuf);
3393   silc_buffer_clear(buf);
3394   silc_buffer_free(buf);
3395
3396   if (rekey) {
3397     *rekey = silc_ske_make_rekey_material(ske, key);
3398     if (!(*rekey))
3399       return NULL;
3400   }
3401
3402   return key;
3403 }
3404
3405 /* Free key material structure */
3406
3407 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3408 {
3409   if (!key)
3410     return;
3411
3412   if (key->send_iv)
3413     silc_free(key->send_iv);
3414   if (key->receive_iv)
3415     silc_free(key->receive_iv);
3416   if (key->send_enc_key) {
3417     memset(key->send_enc_key, 0, key->enc_key_len / 8);
3418     silc_free(key->send_enc_key);
3419   }
3420   if (key->receive_enc_key) {
3421     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3422     silc_free(key->receive_enc_key);
3423   }
3424   if (key->send_hmac_key) {
3425     memset(key->send_hmac_key, 0, key->hmac_key_len);
3426     silc_free(key->send_hmac_key);
3427   }
3428   if (key->receive_hmac_key) {
3429     memset(key->receive_hmac_key, 0, key->hmac_key_len);
3430     silc_free(key->receive_hmac_key);
3431   }
3432   silc_free(key);
3433 }
3434
3435 /* Free rekey material */
3436
3437 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3438 {
3439   if (!rekey)
3440     return;
3441   if (rekey->send_enc_key) {
3442     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3443     silc_free(rekey->send_enc_key);
3444   }
3445   silc_free(rekey->hash);
3446   silc_free(rekey);
3447 }
3448
3449 /* Set keys into use */
3450
3451 SilcBool silc_ske_set_keys(SilcSKE ske,
3452                            SilcSKEKeyMaterial keymat,
3453                            SilcSKESecurityProperties prop,
3454                            SilcCipher *ret_send_key,
3455                            SilcCipher *ret_receive_key,
3456                            SilcHmac *ret_hmac_send,
3457                            SilcHmac *ret_hmac_receive,
3458                            SilcHash *ret_hash)
3459 {
3460   unsigned char iv[SILC_HASH_MAXLEN];
3461   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3462
3463   /* Allocate ciphers to be used in the communication */
3464   if (ret_send_key) {
3465     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3466                            ret_send_key))
3467       return FALSE;
3468   }
3469   if (ret_receive_key) {
3470     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3471                            ret_receive_key))
3472       return FALSE;
3473   }
3474
3475   /* Allocate HMACs */
3476   if (ret_hmac_send) {
3477     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3478                          ret_hmac_send))
3479       return FALSE;
3480   }
3481   if (ret_hmac_receive) {
3482     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3483                          ret_hmac_receive))
3484       return FALSE;
3485   }
3486
3487   /* Allocate hash */
3488   if (ret_hash) {
3489     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3490       return FALSE;
3491   }
3492
3493   /* Set key material */
3494   memset(iv, 0, sizeof(iv));
3495   if (ske->responder) {
3496     if (ret_send_key) {
3497       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3498                           keymat->enc_key_len, TRUE);
3499
3500       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3501         /* Counter mode */
3502         if (!ske->rekeying) {
3503           /* Set IV. */
3504           memcpy(iv, ske->hash, 4);
3505           if (!iv_included)
3506             memcpy(iv + 4, keymat->receive_iv, 8);
3507         } else {
3508           /* Rekey, recompute the truncated hash value. */
3509           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3510           if (!iv_included)
3511             memcpy(iv + 4, keymat->receive_iv, 8);
3512           else
3513             memset(iv + 4, 0, 12);
3514         }
3515
3516         silc_cipher_set_iv(*ret_send_key, iv);
3517       } else {
3518         /* Other modes */
3519         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3520       }
3521     }
3522     if (ret_receive_key) {
3523       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3524                           keymat->enc_key_len, FALSE);
3525
3526       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3527         /* Counter mode */
3528         if (!ske->rekeying) {
3529           /* Set IV. */
3530           memcpy(iv, ske->hash, 4);
3531           if (!iv_included)
3532             memcpy(iv + 4, keymat->send_iv, 8);
3533         } else {
3534           /* Rekey, recompute the truncated hash value. */
3535           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3536           if (!iv_included)
3537             memcpy(iv + 4, keymat->send_iv, 8);
3538           else
3539             memset(iv + 4, 0, 12);
3540         }
3541
3542         silc_cipher_set_iv(*ret_receive_key, iv);
3543       } else {
3544         /* Other modes */
3545         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3546       }
3547     }
3548     if (ret_hmac_send)
3549       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3550                         keymat->hmac_key_len);
3551     if (ret_hmac_receive)
3552       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3553                         keymat->hmac_key_len);
3554   } else {
3555     if (ret_send_key) {
3556       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3557                           keymat->enc_key_len, TRUE);
3558
3559       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3560         /* Counter mode */
3561         if (!ske->rekeying) {
3562           /* Set IV. */
3563           memcpy(iv, ske->hash, 4);
3564           if (!iv_included)
3565             memcpy(iv + 4, keymat->send_iv, 8);
3566         } else {
3567           /* Rekey, recompute the truncated hash value. */
3568           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3569           if (!iv_included)
3570             memcpy(iv + 4, keymat->send_iv, 8);
3571           else
3572             memset(iv + 4, 0, 12);
3573         }
3574
3575         silc_cipher_set_iv(*ret_send_key, iv);
3576       } else {
3577         /* Other modes */
3578         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3579       }
3580     }
3581     if (ret_receive_key) {
3582       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3583                           keymat->enc_key_len, FALSE);
3584
3585       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3586         /* Counter mode */
3587         if (!ske->rekeying) {
3588           /* Set IV.  If IV Included flag was negotiated we only set the
3589              truncated hash value. */
3590           memcpy(iv, ske->hash, 4);
3591           if (!iv_included)
3592             memcpy(iv + 4, keymat->receive_iv, 8);
3593         } else {
3594           /* Rekey, recompute the truncated hash value. */
3595           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3596           if (!iv_included)
3597             memcpy(iv + 4, keymat->receive_iv, 8);
3598           else
3599             memset(iv + 4, 0, 12);
3600         }
3601
3602         silc_cipher_set_iv(*ret_receive_key, iv);
3603       } else {
3604         /* Other modes */
3605         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3606       }
3607     }
3608     if (ret_hmac_send)
3609       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3610                         keymat->hmac_key_len);
3611     if (ret_hmac_receive)
3612       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3613                         keymat->hmac_key_len);
3614   }
3615
3616   return TRUE;
3617 }
3618
3619 const char *silc_ske_status_string[] =
3620 {
3621   /* Official */
3622   "Ok",
3623   "Unexpected error occurred",
3624   "Bad payload in packet",
3625   "Unsupported group",
3626   "Unsupported cipher",
3627   "Unsupported PKCS",
3628   "Unsupported hash function",
3629   "Unsupported HMAC",
3630   "Unsupported public key (or certificate)",
3631   "Incorrect signature",
3632   "Bad or unsupported version",
3633   "Invalid cookie",
3634
3635   /* Other errors */
3636   "Remote did not provide public key",
3637   "Bad reserved field in packet",
3638   "Bad payload length in packet",
3639   "Error computing signature",
3640   "System out of memory",
3641   "Key exchange timeout",
3642
3643   NULL
3644 };
3645
3646 /* Maps status to readable string and returns the string. If string is not
3647    found and empty character string ("") is returned. */
3648
3649 const char *silc_ske_map_status(SilcSKEStatus status)
3650 {
3651   int i;
3652
3653   for (i = 0; silc_ske_status_string[i]; i++)
3654     if (status == i)
3655       return silc_ske_status_string[i];
3656
3657   return "";
3658 }
3659
3660 /* Parses remote host's version string. */
3661
3662 SilcBool silc_ske_parse_version(SilcSKE ske,
3663                                 SilcUInt32 *protocol_version,
3664                                 char **protocol_version_string,
3665                                 SilcUInt32 *software_version,
3666                                 char **software_version_string,
3667                                 char **vendor_version)
3668 {
3669   return silc_parse_version_string(ske->remote_version,
3670                                    protocol_version,
3671                                    protocol_version_string,
3672                                    software_version,
3673                                    software_version_string,
3674                                    vendor_version);
3675 }
3676
3677 /* Get security properties */
3678
3679 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3680 {
3681   return ske->prop;
3682 }
3683
3684 /* Get key material */
3685
3686 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3687 {
3688   return ske->keymat;
3689 }