Fix compilation warnings
[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                                       SilcBool small_proposal)
869 {
870   SilcSKEStartPayload rp;
871   int i;
872
873   SILC_LOG_DEBUG(("Assembling KE Start Payload"));
874
875   rp = silc_calloc(1, sizeof(*rp));
876   if (!rp)
877     return NULL;
878
879   /* Set flags */
880   rp->flags = (unsigned char)flags;
881
882   /* Set random cookie */
883   rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
884   if (!rp->cookie) {
885     silc_free(rp);
886     return NULL;
887   }
888   for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
889     rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
890   rp->cookie_len = SILC_SKE_COOKIE_LEN;
891
892   /* In case IV included flag and session port is set the first 16-bits of
893      cookie will include our session port. */
894   if (flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port)
895     SILC_PUT16_MSB(ske->session_port, rp->cookie);
896
897   /* Put version */
898   rp->version = strdup(version);
899   if (rp->version)
900     rp->version_len = strlen(version);
901
902   /* Get supported Key Exhange groups */
903   rp->ke_grp_list = silc_ske_get_supported_groups(small_proposal);
904   if (rp->ke_grp_list)
905     rp->ke_grp_len = strlen(rp->ke_grp_list);
906
907   /* Get supported PKCS algorithms */
908   if (small_proposal)
909     rp->pkcs_alg_list = strdup(silc_default_pkcs_alg[0].name);
910   else
911     rp->pkcs_alg_list = silc_pkcs_get_supported();
912   if (rp->pkcs_alg_list)
913     rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
914
915   /* Get supported encryption algorithms */
916   if (small_proposal)
917     rp->enc_alg_list = strdup(silc_default_ciphers[0].name);
918   else
919     rp->enc_alg_list = silc_cipher_get_supported();
920   if (rp->enc_alg_list)
921     rp->enc_alg_len = strlen(rp->enc_alg_list);
922
923   /* Get supported hash algorithms */
924   if (small_proposal)
925     rp->hash_alg_list = strdup(silc_default_hash[0].name);
926   else
927     rp->hash_alg_list = silc_hash_get_supported();
928   if (rp->hash_alg_list)
929     rp->hash_alg_len = strlen(rp->hash_alg_list);
930
931   /* Get supported HMACs */
932   if (small_proposal)
933     rp->hmac_alg_list = strdup(silc_default_hmacs[0].name);
934   else
935     rp->hmac_alg_list = silc_hmac_get_supported();
936   if (rp->hmac_alg_list)
937     rp->hmac_alg_len = strlen(rp->hmac_alg_list);
938
939   if (!small_proposal) {
940     /* XXX */
941     /* Get supported compression algorithms */
942     rp->comp_alg_list = strdup("none");
943     rp->comp_alg_len = strlen("none");
944   }
945
946   rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
947     2 + rp->version_len +
948     2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
949     2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
950     2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
951
952   return rp;
953 }
954
955 /* Packet retransmission callback. */
956
957 SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
958 {
959   SilcSKE ske = context;
960
961   if (ske->retry_count++ >= SILC_SKE_RETRY_COUNT ||
962       ske->aborted) {
963     SILC_LOG_DEBUG(("Retransmission limit reached, packet was lost"));
964     ske->retry_count = 0;
965     ske->retry_timer = SILC_SKE_RETRY_MIN;
966     silc_free(ske->retrans.data);
967     ske->retrans.data = NULL;
968     ske->status = SILC_SKE_STATUS_TIMEOUT;
969     silc_ske_notify_failure(ske);
970     silc_fsm_continue_sync(&ske->fsm);
971     return;
972   }
973
974   SILC_LOG_DEBUG(("Retransmitting packet"));
975   silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
976                        ske->retrans.data, ske->retrans.data_len);
977 }
978
979 /* Install retransmission timer */
980
981 static SilcBool silc_ske_install_retransmission(SilcSKE ske)
982 {
983   if (!silc_packet_stream_is_udp(ske->stream))
984     return FALSE;
985
986   if (ske->retrans.data) {
987     SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
988                     ske->retry_timer));
989     silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
990                                    ske, ske->retry_timer, 0);
991   }
992   ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
993                       (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
994   return TRUE;
995 }
996
997 /* Sends SILC packet.  Handles retransmissions with UDP streams. */
998
999 static SilcBool silc_ske_packet_send(SilcSKE ske,
1000                                      SilcPacketType type,
1001                                      SilcPacketFlags flags,
1002                                      const unsigned char *data,
1003                                      SilcUInt32 data_len)
1004 {
1005   SilcBool ret;
1006
1007   /* Send the packet */
1008   ret = silc_packet_send(ske->stream, type, flags, data, data_len);
1009
1010   if (silc_packet_stream_is_udp(ske->stream) &&
1011       type != SILC_PACKET_FAILURE && type != SILC_PACKET_REKEY) {
1012     silc_free(ske->retrans.data);
1013     ske->retrans.type = type;
1014     ske->retrans.flags = flags;
1015     ske->retrans.data = silc_memdup(data, data_len);
1016     if (ske->retrans.data) {
1017       ske->retrans.data_len = data_len;
1018       silc_ske_install_retransmission(ske);
1019     }
1020   }
1021
1022   return ret;
1023 }
1024
1025 /* Calls completion callback.  Completion is called always in this function
1026    and must not be called anywhere else. */
1027
1028 static void silc_ske_completion(SilcSKE ske)
1029 {
1030   /* Call the completion callback */
1031   if (!ske->aborted && ske->callbacks->completed) {
1032     if (ske->status != SILC_SKE_STATUS_OK)
1033       ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1034                                 ske->callbacks->context);
1035     else
1036       ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1037                                 ske->rekey, ske->callbacks->context);
1038   }
1039 }
1040
1041 /* SKE FSM destructor. */
1042
1043 static void silc_ske_finished(SilcFSM fsm, void *fsm_context,
1044                               void *destructor_context)
1045 {
1046   SilcSKE ske = fsm_context;
1047   silc_ske_free(ske);
1048 }
1049
1050 /* Key exchange timeout task callback */
1051
1052 SILC_TASK_CALLBACK(silc_ske_timeout)
1053 {
1054   SilcSKE ske = context;
1055
1056   SILC_LOG_DEBUG(("Timeout"));
1057
1058   ske->packet = NULL;
1059   ske->status = SILC_SKE_STATUS_TIMEOUT;
1060   silc_ske_notify_failure(ske);
1061
1062   silc_fsm_continue_sync(&ske->fsm);
1063 }
1064
1065 /* Key exchange timeout task callback */
1066
1067 SILC_TASK_CALLBACK(silc_ske_probe_timeout)
1068 {
1069   SilcSKE ske = context;
1070
1071   SILC_LOG_DEBUG(("Probe timeout"));
1072
1073   ske->packet = NULL;
1074   ske->status = SILC_SKE_STATUS_PROBE_TIMEOUT;
1075   silc_ske_notify_failure(ske);
1076
1077   silc_fsm_continue_sync(&ske->fsm);
1078 }
1079
1080 /******************************* Protocol API *******************************/
1081
1082 /* Allocates new SKE object. */
1083
1084 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1085                        SilcSKR repository, SilcPublicKey public_key,
1086                        SilcPrivateKey private_key, void *context)
1087 {
1088   SilcSKE ske;
1089
1090   SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1091
1092   if (!rng || !schedule)
1093     return NULL;
1094
1095   if (!public_key) {
1096     SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1097     return NULL;
1098   }
1099
1100   ske = silc_calloc(1, sizeof(*ske));
1101   if (!ske)
1102     return NULL;
1103   ske->status = SILC_SKE_STATUS_OK;
1104   ske->rng = rng;
1105   ske->repository = repository;
1106   ske->user_data = context;
1107   ske->schedule = schedule;
1108   ske->public_key = public_key;
1109   ske->private_key = private_key;
1110   ske->retry_timer = SILC_SKE_RETRY_MIN;
1111   ske->refcnt = 1;
1112
1113   return ske;
1114 }
1115
1116 /* Free's SKE object. */
1117
1118 void silc_ske_free(SilcSKE ske)
1119 {
1120   if (!ske)
1121     return;
1122
1123   SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu",
1124                   ske, ske->aborted, ske->refcnt));
1125
1126   if (ske->aborted) {
1127     /*
1128      * If already aborted, destroy the session immediately.  Only do the
1129      * notification work if we have not already though, as doing so twice
1130      * results in memory corruption.  We may have silc_ske_free called
1131      * twice, once when the abort is requested, and then again when the
1132      * FSM finish routine is called.  We have to be prepared to handle
1133      * that case.
1134      */
1135     ske->packet = NULL;
1136     ske->status = SILC_SKE_STATUS_ERROR;
1137
1138     silc_ske_notify_failure(ske);
1139
1140     if (silc_fsm_is_started(&ske->fsm))
1141       silc_fsm_continue_sync(&ske->fsm);
1142     else
1143       SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske));
1144   }
1145
1146   ske->refcnt--;
1147   if (ske->refcnt > 0)
1148     return;
1149
1150   /* Free start payload */
1151   if (ske->start_payload)
1152     silc_ske_payload_start_free(ske->start_payload);
1153
1154   /* Free KE payload */
1155   if (ske->ke1_payload)
1156     silc_ske_payload_ke_free(ske->ke1_payload);
1157   if (ske->ke2_payload)
1158     silc_ske_payload_ke_free(ske->ke2_payload);
1159   silc_free(ske->remote_version);
1160
1161   /* Free rest */
1162   if (ske->prop) {
1163     if (ske->prop->group)
1164       silc_ske_group_free(ske->prop->group);
1165     if (ske->prop->cipher)
1166       silc_cipher_free(ske->prop->cipher);
1167     if (ske->prop->hash)
1168       silc_hash_free(ske->prop->hash);
1169     if (ske->prop->hmac)
1170       silc_hmac_free(ske->prop->hmac);
1171     if (ske->prop->public_key)
1172       silc_pkcs_public_key_free(ske->prop->public_key);
1173     silc_free(ske->prop);
1174   }
1175   if (ske->keymat)
1176     silc_ske_free_key_material(ske->keymat);
1177   if (ske->start_payload_copy)
1178     silc_buffer_free(ske->start_payload_copy);
1179   if (ske->x) {
1180     silc_mp_uninit(ske->x);
1181     silc_free(ske->x);
1182   }
1183   if (ske->KEY) {
1184     silc_mp_uninit(ske->KEY);
1185     silc_free(ske->KEY);
1186   }
1187   silc_free(ske->retrans.data);
1188   silc_free(ske->hash);
1189   silc_free(ske->callbacks);
1190
1191   memset(ske, 0xdd, sizeof(*ske));
1192   silc_free(ske);
1193 }
1194
1195 /* Return user context */
1196
1197 void *silc_ske_get_context(SilcSKE ske)
1198 {
1199   return ske->user_data;
1200 }
1201
1202 /* Sets protocol callbacks */
1203
1204 void silc_ske_set_callbacks(SilcSKE ske,
1205                             SilcSKEVerifyCb verify_key,
1206                             SilcSKECompletionCb completed,
1207                             void *context)
1208 {
1209   if (ske->callbacks)
1210     silc_free(ske->callbacks);
1211   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1212   if (!ske->callbacks)
1213     return;
1214   ske->callbacks->verify_key = verify_key;
1215   ske->callbacks->completed = completed;
1216   ske->callbacks->context = context;
1217 }
1218
1219
1220 /******************************** Initiator *********************************/
1221
1222 /* Start protocol.  Send our proposal */
1223
1224 SILC_FSM_STATE(silc_ske_st_initiator_start)
1225 {
1226   SilcSKE ske = fsm_context;
1227   SilcBuffer payload_buf;
1228   SilcStatus status;
1229
1230   SILC_LOG_DEBUG(("Start"));
1231
1232   if (ske->aborted) {
1233     /** Aborted */
1234     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1235     return SILC_FSM_CONTINUE;
1236   }
1237
1238   /* Encode the payload */
1239   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1240                                          &payload_buf);
1241   if (status != SILC_SKE_STATUS_OK) {
1242     /** Error encoding Start Payload */
1243     ske->status = status;
1244     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1245     return SILC_FSM_CONTINUE;
1246   }
1247
1248   /* Save the the payload buffer for future use. It is later used to
1249      compute the HASH value. */
1250   ske->start_payload_copy = payload_buf;
1251
1252   /* Send the packet. */
1253   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1254                             silc_buffer_data(payload_buf),
1255                             silc_buffer_len(payload_buf))) {
1256     /** Error sending packet */
1257     SILC_LOG_DEBUG(("Error sending packet"));
1258     ske->status = SILC_SKE_STATUS_ERROR;
1259     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1260     return SILC_FSM_CONTINUE;
1261   }
1262
1263   /** Wait for responder proposal */
1264   SILC_LOG_DEBUG(("Waiting for responder proposal"));
1265   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1266   return SILC_FSM_WAIT;
1267 }
1268
1269 /* Phase-1.  Receives responder's proposal */
1270
1271 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1272 {
1273   SilcSKE ske = fsm_context;
1274   SilcSKEStatus status;
1275   SilcSKEStartPayload payload;
1276   SilcSKESecurityProperties prop;
1277   SilcSKEDiffieHellmanGroup group = NULL;
1278   SilcBuffer packet_buf = &ske->packet->buffer;
1279   SilcUInt16 remote_port = 0;
1280   SilcID id;
1281   int coff = 0;
1282
1283   SILC_LOG_DEBUG(("Start"));
1284
1285   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1286     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1287     if (silc_ske_install_retransmission(ske)) {
1288       silc_packet_free(ske->packet);
1289       ske->packet = NULL;
1290       return SILC_FSM_WAIT;
1291     } else {
1292       silc_packet_free(ske->packet);
1293       ske->packet = NULL;
1294       ske->status = SILC_SKE_STATUS_ERROR;
1295       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1296       return SILC_FSM_CONTINUE;
1297     }
1298   }
1299
1300   silc_schedule_task_del_by_all(ske->schedule, 0, silc_ske_probe_timeout, ske);
1301
1302   /* Decode the payload */
1303   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1304   if (status != SILC_SKE_STATUS_OK) {
1305     /** Error decoding Start Payload */
1306     silc_packet_free(ske->packet);
1307     ske->packet = NULL;
1308     ske->status = status;
1309     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1310     return SILC_FSM_CONTINUE;
1311   }
1312
1313   /* Get remote ID and set it to stream */
1314   if (ske->packet->src_id_len &&
1315       (ske->packet->src_id_type == SILC_ID_SERVER ||
1316        ske->packet->src_id_type == SILC_ID_CLIENT)) {
1317     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1318                    ske->packet->src_id_type,
1319                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1320                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1321                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1322                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1323     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1324                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1325                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1326   }
1327
1328   silc_packet_free(ske->packet);
1329   ske->packet = NULL;
1330
1331   /* Check that the cookie is returned unmodified.  In case IV included
1332      flag and session port has been set, the first two bytes of cookie
1333      are the session port and we ignore them in this check. */
1334   if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1335     /* Take remote port */
1336     SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1337     coff = 2;
1338   }
1339   if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1340              SILC_SKE_COOKIE_LEN - coff)) {
1341     /** Invalid cookie */
1342     SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1343     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1344     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1345     return SILC_FSM_CONTINUE;
1346   }
1347
1348   /* Check version string */
1349   ske->remote_version = silc_memdup(payload->version, payload->version_len);
1350   status = silc_ske_check_version(ske);
1351   if (status != SILC_SKE_STATUS_OK) {
1352     /** Version mismatch */
1353     ske->status = status;
1354     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355     return SILC_FSM_CONTINUE;
1356   }
1357
1358   /* Free our KE Start Payload context, we don't need it anymore. */
1359   silc_ske_payload_start_free(ske->start_payload);
1360   ske->start_payload = NULL;
1361
1362   /* Take the selected security properties into use while doing
1363      the key exchange.  This is used only while doing the key
1364      exchange. */
1365   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1366   if (!ske->prop)
1367     goto err;
1368   prop->flags = payload->flags;
1369   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1370   if (status != SILC_SKE_STATUS_OK)
1371     goto err;
1372
1373   prop->group = group;
1374   prop->remote_port = remote_port;
1375
1376   if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1377     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1378     goto err;
1379   }
1380   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1381     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1382     goto err;
1383   }
1384   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1385     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1386     goto err;
1387   }
1388   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1389     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1390     goto err;
1391   }
1392
1393   /* Save remote's KE Start Payload */
1394   ske->start_payload = payload;
1395
1396   /** Send KE Payload */
1397   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1398   return SILC_FSM_CONTINUE;
1399
1400  err:
1401   if (payload)
1402     silc_ske_payload_start_free(payload);
1403   if (group)
1404     silc_ske_group_free(group);
1405   if (prop) {
1406     if (prop->cipher)
1407       silc_cipher_free(prop->cipher);
1408     if (prop->hash)
1409       silc_hash_free(prop->hash);
1410     if (prop->hmac)
1411       silc_hmac_free(prop->hmac);
1412     silc_free(prop);
1413   }
1414   ske->prop = NULL;
1415
1416   if (status == SILC_SKE_STATUS_OK)
1417     status = SILC_SKE_STATUS_ERROR;
1418
1419   /** Error */
1420   ske->status = status;
1421   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1422   return SILC_FSM_CONTINUE;
1423 }
1424
1425 /* Phase-2.  Send KE payload */
1426
1427 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1428 {
1429   SilcSKE ske = fsm_context;
1430   SilcSKEStatus status;
1431   SilcBuffer payload_buf;
1432   SilcMPInt *x;
1433   SilcSKEKEPayload payload;
1434   SilcUInt32 pk_len;
1435
1436   SILC_LOG_DEBUG(("Start"));
1437
1438   /* Create the random number x, 1 < x < q. */
1439   x = silc_calloc(1, sizeof(*x));
1440   if (!x) {
1441     /** Out of memory */
1442     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1443     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1444     return SILC_FSM_CONTINUE;
1445   }
1446   silc_mp_init(x);
1447   status =
1448     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1449                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1450                         x);
1451   if (status != SILC_SKE_STATUS_OK) {
1452     /** Error generating random number */
1453     silc_mp_uninit(x);
1454     silc_free(x);
1455     ske->status = status;
1456     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1457     return SILC_FSM_CONTINUE;
1458   }
1459
1460   /* Encode the result to Key Exchange Payload. */
1461
1462   payload = silc_calloc(1, sizeof(*payload));
1463   if (!payload) {
1464     /** Out of memory */
1465     silc_mp_uninit(x);
1466     silc_free(x);
1467     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1468     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1469     return SILC_FSM_CONTINUE;
1470   }
1471   ske->ke1_payload = payload;
1472
1473   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1474
1475   /* Do the Diffie Hellman computation, e = g ^ x mod p */
1476   silc_mp_init(&payload->x);
1477   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1478                   &ske->prop->group->group);
1479
1480   /* Get public key */
1481   payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1482   if (!payload->pk_data) {
1483     /** Error encoding public key */
1484     silc_mp_uninit(x);
1485     silc_free(x);
1486     silc_mp_uninit(&payload->x);
1487     silc_free(payload);
1488     ske->ke1_payload = NULL;
1489     ske->status = SILC_SKE_STATUS_ERROR;
1490     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1491     return SILC_FSM_CONTINUE;
1492   }
1493   payload->pk_len = pk_len;
1494   payload->pk_type = silc_pkcs_get_type(ske->public_key);
1495
1496   /* Compute signature data if we are doing mutual authentication */
1497   if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1498     unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1];
1499     SilcUInt32 hash_len, sign_len;
1500
1501     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1502     SILC_LOG_DEBUG(("Computing HASH_i value"));
1503
1504     /* Compute the hash value */
1505     memset(hash, 0, sizeof(hash));
1506     if (silc_ske_make_hash(ske, hash, &hash_len, TRUE) != SILC_SKE_STATUS_OK)
1507       {
1508         /** Error computing hash */
1509         silc_mp_uninit(x);
1510         silc_free(x);
1511         silc_mp_uninit(&payload->x);
1512         silc_free(payload->pk_data);
1513         silc_free(payload);
1514         ske->ke1_payload = NULL;
1515         ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1516         silc_fsm_next(fsm, silc_ske_st_initiator_error);
1517         return SILC_FSM_CONTINUE;
1518       }
1519
1520     SILC_LOG_DEBUG(("Signing HASH_i value"));
1521
1522     /* Sign the hash value */
1523     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1524                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1525       /** Error computing signature */
1526       silc_mp_uninit(x);
1527       silc_free(x);
1528       silc_mp_uninit(&payload->x);
1529       silc_free(payload->pk_data);
1530       silc_free(payload);
1531       ske->ke1_payload = NULL;
1532       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1533       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1534       return SILC_FSM_CONTINUE;
1535     }
1536     payload->sign_data = silc_memdup(sign, sign_len);
1537     if (payload->sign_data)
1538       payload->sign_len = sign_len;
1539     memset(sign, 0, sizeof(sign));
1540   }
1541
1542   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1543   if (status != SILC_SKE_STATUS_OK) {
1544     /** Error encoding KE payload */
1545     silc_mp_uninit(x);
1546     silc_free(x);
1547     silc_mp_uninit(&payload->x);
1548     silc_free(payload->pk_data);
1549     silc_free(payload->sign_data);
1550     silc_free(payload);
1551     ske->ke1_payload = NULL;
1552     ske->status = status;
1553     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1554     return SILC_FSM_CONTINUE;
1555   }
1556
1557   ske->x = x;
1558
1559   /* Check for backwards compatibility */
1560
1561   /* Send the packet. */
1562   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1563                             silc_buffer_data(payload_buf),
1564                             silc_buffer_len(payload_buf))) {
1565     /** Error sending packet */
1566     SILC_LOG_DEBUG(("Error sending packet"));
1567     ske->status = SILC_SKE_STATUS_ERROR;
1568     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1569     return SILC_FSM_CONTINUE;
1570   }
1571
1572   silc_buffer_free(payload_buf);
1573
1574   /** Waiting responder's KE payload */
1575   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1576   return SILC_FSM_WAIT;
1577 }
1578
1579 /* Phase-3.  Process responder's KE payload */
1580
1581 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1582 {
1583   SilcSKE ske = fsm_context;
1584   SilcSKEStatus status;
1585   SilcSKEKEPayload payload;
1586   SilcMPInt *KEY;
1587   SilcBuffer packet_buf = &ske->packet->buffer;
1588
1589   SILC_LOG_DEBUG(("Start"));
1590
1591   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1592     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1593     if (silc_ske_install_retransmission(ske)) {
1594       silc_packet_free(ske->packet);
1595       ske->packet = NULL;
1596       return SILC_FSM_WAIT;
1597     } else {
1598       silc_packet_free(ske->packet);
1599       ske->packet = NULL;
1600       ske->status = SILC_SKE_STATUS_ERROR;
1601       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1602       return SILC_FSM_CONTINUE;
1603     }
1604   }
1605
1606   /* Decode the payload */
1607   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1608   if (status != SILC_SKE_STATUS_OK) {
1609     /** Error decoding KE payload */
1610     silc_packet_free(ske->packet);
1611     ske->packet = NULL;
1612     ske->status = status;
1613     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1614     return SILC_FSM_CONTINUE;
1615   }
1616   silc_packet_free(ske->packet);
1617   ske->packet = NULL;
1618   ske->ke2_payload = payload;
1619
1620   if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1621     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1622                     "even though we require it"));
1623     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1624     goto err;
1625   }
1626
1627   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1628
1629   /* Compute the shared secret key */
1630   KEY = silc_calloc(1, sizeof(*KEY));
1631   if (!KEY) {
1632     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1633     goto err;
1634   }
1635   silc_mp_init(KEY);
1636   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1637   ske->KEY = KEY;
1638
1639   /* Decode the remote's public key */
1640   if (payload->pk_data &&
1641       !silc_pkcs_public_key_alloc(payload->pk_type,
1642                                   payload->pk_data, payload->pk_len,
1643                                   &ske->prop->public_key)) {
1644     SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1645     status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1646     goto err;
1647   }
1648
1649   if (ske->prop->public_key && (ske->callbacks->verify_key ||
1650                                 ske->repository)) {
1651     SILC_LOG_DEBUG(("Verifying public key"));
1652
1653     /** Waiting public key verification */
1654     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1655
1656     /* If repository is provided, verify the key from there. */
1657     if (ske->repository) {
1658       SilcSKRFind find;
1659
1660       find = silc_skr_find_alloc();
1661       if (!find) {
1662         status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1663         goto err;
1664       }
1665       silc_skr_find_set_pkcs_type(find,
1666                                   silc_pkcs_get_type(ske->prop->public_key));
1667       silc_skr_find_set_public_key(find, ske->prop->public_key);
1668       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1669
1670       /* Find key from repository */
1671       SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1672                                   find, silc_ske_skr_callback, ske));
1673     } else {
1674       /* Verify from application */
1675       SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1676                                                ske->callbacks->context,
1677                                                silc_ske_pk_verified, NULL));
1678     }
1679     /* NOT REACHED */
1680   }
1681
1682   /** Process key material */
1683   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1684   return SILC_FSM_CONTINUE;
1685
1686  err:
1687   silc_ske_payload_ke_free(payload);
1688   ske->ke2_payload = NULL;
1689
1690   silc_mp_uninit(ske->KEY);
1691   silc_free(ske->KEY);
1692   ske->KEY = NULL;
1693
1694   if (status == SILC_SKE_STATUS_OK)
1695     return SILC_SKE_STATUS_ERROR;
1696
1697   /** Error */
1698   ske->status = status;
1699   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1700   return SILC_FSM_CONTINUE;
1701 }
1702
1703 /* Process key material */
1704
1705 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1706 {
1707   SilcSKE ske = fsm_context;
1708   SilcSKEStatus status;
1709   SilcSKEKEPayload payload;
1710   unsigned char hash[SILC_HASH_MAXLEN];
1711   SilcUInt32 hash_len = 0;
1712   int key_len, block_len;
1713
1714   if (ske->aborted) {
1715     /** Aborted */
1716     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1717     return SILC_FSM_CONTINUE;
1718   }
1719
1720   /* Check result of public key verification */
1721   if (ske->status != SILC_SKE_STATUS_OK) {
1722     /** Public key not verified */
1723     SILC_LOG_DEBUG(("Public key verification failed"));
1724     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1725     return SILC_FSM_CONTINUE;
1726   }
1727
1728   payload = ske->ke2_payload;
1729
1730   /* Compute the HASH value */
1731   SILC_LOG_DEBUG(("Computing HASH value"));
1732   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1733   if (status != SILC_SKE_STATUS_OK)
1734     goto err;
1735   ske->hash = silc_memdup(hash, hash_len);
1736   if (!ske->hash) {
1737     status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1738     goto err;
1739   }
1740   ske->hash_len = hash_len;
1741
1742   if (ske->prop->public_key) {
1743     SILC_LOG_DEBUG(("Public key is authentic"));
1744     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1745
1746     /* Verify signature */
1747     if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1748                           payload->sign_len, hash, hash_len, NULL)) {
1749       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1750       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1751       goto err;
1752     }
1753
1754     SILC_LOG_DEBUG(("Signature is Ok"));
1755     memset(hash, 'F', hash_len);
1756   }
1757
1758   ske->status = SILC_SKE_STATUS_OK;
1759
1760   /* In case we are doing rekey move to finish it.  */
1761   if (ske->rekey) {
1762     /** Finish rekey */
1763     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1764     return SILC_FSM_CONTINUE;
1765   }
1766
1767   /* Process key material */
1768   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1769   block_len = silc_cipher_get_block_len(ske->prop->cipher);
1770   hash_len = silc_hash_len(ske->prop->hash);
1771   ske->keymat = silc_ske_process_key_material(ske, block_len,
1772                                               key_len, hash_len,
1773                                               &ske->rekey);
1774   if (!ske->keymat) {
1775     SILC_LOG_ERROR(("Error processing key material"));
1776     status = SILC_SKE_STATUS_ERROR;
1777     goto err;
1778   }
1779
1780   if (!ske->no_acks) {
1781     /* Send SUCCESS packet */
1782     SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1783     if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1784       /** Error sending packet */
1785       SILC_LOG_DEBUG(("Error sending packet"));
1786       ske->status = SILC_SKE_STATUS_ERROR;
1787       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1788       return SILC_FSM_CONTINUE;
1789     }
1790
1791     /** Waiting completion */
1792     silc_fsm_next(fsm, silc_ske_st_initiator_end);
1793     return SILC_FSM_WAIT;
1794   } else {
1795     /** Complete protocol */
1796     silc_fsm_next(fsm, silc_ske_st_initiator_end);
1797     return SILC_FSM_CONTINUE;
1798   }
1799
1800  err:
1801   memset(hash, 'F', sizeof(hash));
1802   silc_ske_payload_ke_free(payload);
1803   ske->ke2_payload = NULL;
1804
1805   silc_mp_uninit(ske->KEY);
1806   silc_free(ske->KEY);
1807   ske->KEY = NULL;
1808
1809   if (ske->hash) {
1810     memset(ske->hash, 'F', hash_len);
1811     silc_free(ske->hash);
1812     ske->hash = NULL;
1813   }
1814
1815   if (status == SILC_SKE_STATUS_OK)
1816     status = SILC_SKE_STATUS_ERROR;
1817
1818   /** Error */
1819   ske->status = status;
1820   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1821   return SILC_FSM_CONTINUE;
1822 }
1823
1824 /* Protocol completed */
1825
1826 SILC_FSM_STATE(silc_ske_st_initiator_end)
1827 {
1828   SilcSKE ske = fsm_context;
1829
1830   SILC_LOG_DEBUG(("Start"));
1831
1832   if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
1833     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1834     if (silc_ske_install_retransmission(ske)) {
1835       silc_packet_free(ske->packet);
1836       ske->packet = NULL;
1837       return SILC_FSM_WAIT;
1838     } else {
1839       silc_packet_free(ske->packet);
1840       ske->packet = NULL;
1841       ske->status = SILC_SKE_STATUS_ERROR;
1842       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1843       return SILC_FSM_CONTINUE;
1844     }
1845   }
1846
1847   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1848
1849   if (ske->packet)
1850     silc_packet_free(ske->packet);
1851   ske->packet = NULL;
1852   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1853   silc_schedule_task_del_by_context(ske->schedule, ske);
1854
1855   /* Call completion */
1856   silc_ske_completion(ske);
1857
1858   return SILC_FSM_FINISH;
1859 }
1860
1861 /* Aborted by application */
1862
1863 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1864 {
1865   SilcSKE ske = fsm_context;
1866   unsigned char data[4];
1867
1868   SILC_LOG_DEBUG(("Aborted by caller"));
1869
1870   /* Send FAILURE packet */
1871   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1872   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1873
1874   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1875   silc_schedule_task_del_by_context(ske->schedule, ske);
1876
1877   /* Call completion */
1878   silc_ske_completion(ske);
1879
1880   return SILC_FSM_FINISH;
1881 }
1882
1883 /* Error occurred.  Send error to remote host */
1884
1885 SILC_FSM_STATE(silc_ske_st_initiator_error)
1886 {
1887   SilcSKE ske = fsm_context;
1888   SilcUInt32 status;
1889   unsigned char data[4];
1890
1891   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1892                   silc_ske_map_status(ske->status), ske->status));
1893
1894   status = ske->status;
1895   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1896     status = SILC_SKE_STATUS_ERROR;
1897
1898   /* Send FAILURE packet */
1899   SILC_PUT32_MSB(status, data);
1900   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1901
1902   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1903   silc_schedule_task_del_by_context(ske->schedule, ske);
1904
1905   /* Call completion */
1906   silc_ske_completion(ske);
1907
1908   return SILC_FSM_FINISH;
1909 }
1910
1911 /* Failure received from remote */
1912
1913 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1914 {
1915   SilcSKE ske = fsm_context;
1916   SilcUInt32 error = ske->status;
1917
1918   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1919     SILC_GET32_MSB(error, ske->packet->buffer.data);
1920     silc_packet_free(ske->packet);
1921     ske->packet = NULL;
1922   }
1923   if (error == SILC_SKE_STATUS_OK)
1924     error = SILC_SKE_STATUS_ERROR;
1925   ske->status = error;
1926
1927   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1928                   silc_ske_map_status(ske->status), ske->status));
1929
1930   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1931   silc_schedule_task_del_by_context(ske->schedule, ske);
1932
1933   /* Call completion */
1934   silc_ske_completion(ske);
1935
1936   return SILC_FSM_FINISH;
1937 }
1938
1939 /* Starts the protocol as initiator */
1940
1941 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1942                                       SilcPacketStream stream,
1943                                       SilcSKEParams params,
1944                                       SilcSKEStartPayload start_payload)
1945 {
1946   SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; "
1947                   "start_payload=%p", ske, stream, params, start_payload));
1948
1949   if (!ske || !stream || !params || !params->version)
1950     return NULL;
1951
1952   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1953     return NULL;
1954
1955   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1956     return NULL;
1957
1958   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1959     ske->session_port = params->session_port;
1960
1961   /* Generate security properties if not provided */
1962   if (!start_payload && !params->prop) {
1963     start_payload =
1964       silc_ske_assemble_security_properties(ske, params->flags,
1965                                             params->version,
1966                                             params->small_proposal);
1967     if (!start_payload)
1968       return NULL;
1969   }
1970
1971   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1972   ske->probe_timeout = (params->probe_timeout_secs ?
1973                         params->probe_timeout_secs : 30);
1974   ske->start_payload = start_payload;
1975   ske->prop = params->prop;
1976   ske->version = params->version;
1977   ske->no_acks = params->no_acks;
1978   ++ske->refcnt;
1979
1980   /* Link to packet stream to get key exchange packets */
1981   ske->stream = stream;
1982   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1983                           SILC_PACKET_KEY_EXCHANGE,
1984                           SILC_PACKET_KEY_EXCHANGE_2,
1985                           SILC_PACKET_SUCCESS,
1986                           SILC_PACKET_FAILURE, -1);
1987
1988   /* Add key exchange timeout */
1989   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1990                                  ske, ske->timeout, 0);
1991   if (ske->timeout != ske->probe_timeout)
1992     silc_schedule_task_add_timeout(ske->schedule, silc_ske_probe_timeout,
1993                                    ske, ske->probe_timeout, 0);
1994
1995   /* Start SKE as initiator */
1996   if (!ske->prop)
1997     silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1998   else
1999     silc_fsm_start(&ske->fsm, silc_ske_st_initiator_phase2);
2000
2001   return &ske->op;
2002 }
2003
2004 /******************************** Responder *********************************/
2005
2006 /* Start protocol as responder.  Wait initiator's start payload */
2007
2008 SILC_FSM_STATE(silc_ske_st_responder_start)
2009 {
2010   SilcSKE ske = fsm_context;
2011
2012   SILC_LOG_DEBUG(("Start"));
2013
2014   if (ske->aborted) {
2015     /** Aborted */
2016     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2017     return SILC_FSM_CONTINUE;
2018   }
2019
2020   /** Wait for initiator */
2021   if (!ske->prop)
2022     silc_fsm_next(fsm, silc_ske_st_responder_phase1);
2023   else
2024     silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2025   return SILC_FSM_WAIT;
2026 }
2027
2028 /* Decode initiator's start payload.  Select the security properties from
2029    the initiator's start payload and send our reply start payload back. */
2030
2031 SILC_FSM_STATE(silc_ske_st_responder_phase1)
2032 {
2033   SilcSKE ske = fsm_context;
2034   SilcSKEStatus status;
2035   SilcSKEStartPayload remote_payload = NULL;
2036   SilcBuffer packet_buf = &ske->packet->buffer;
2037   SilcID id;
2038
2039   SILC_LOG_DEBUG(("Start"));
2040
2041   /* Decode the payload */
2042   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
2043   if (status != SILC_SKE_STATUS_OK) {
2044     /** Error decoding Start Payload */
2045     silc_packet_free(ske->packet);
2046     ske->packet = NULL;
2047     ske->status = status;
2048     silc_fsm_next(fsm, silc_ske_st_responder_error);
2049     return SILC_FSM_CONTINUE;
2050   }
2051
2052   /* Get remote ID and set it to stream */
2053   if (ske->packet->src_id_len &&
2054       (ske->packet->src_id_type == SILC_ID_SERVER ||
2055        ske->packet->src_id_type == SILC_ID_CLIENT)) {
2056     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2057                    ske->packet->src_id_type,
2058                    (ske->packet->src_id_type == SILC_ID_SERVER ?
2059                     (void *)&id.u.server_id : (void *)&id.u.client_id),
2060                    (ske->packet->src_id_type == SILC_ID_SERVER ?
2061                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2062     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2063                         (ske->packet->src_id_type == SILC_ID_SERVER ?
2064                          (void *)&id.u.server_id : (void *)&id.u.client_id));
2065   }
2066
2067   /* Take a copy of the payload buffer for future use. It is used to
2068      compute the HASH value. */
2069   ske->start_payload_copy = silc_buffer_copy(packet_buf);
2070   if (!ske->start_payload_copy) {
2071     silc_packet_free(ske->packet);
2072     ske->packet = NULL;
2073     ske->status = status;
2074     silc_fsm_next(fsm, silc_ske_st_responder_error);
2075     return SILC_FSM_CONTINUE;
2076   }
2077
2078   silc_packet_free(ske->packet);
2079   ske->packet = NULL;
2080
2081   /* Force the mutual authentication flag if we want to do it. */
2082   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2083     SILC_LOG_DEBUG(("Force mutual authentication"));
2084     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2085   }
2086
2087   /* Force PFS flag if we require it */
2088   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2089     SILC_LOG_DEBUG(("Force PFS"));
2090     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2091   }
2092
2093   /* Disable IV Included flag if requested */
2094   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2095       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2096     SILC_LOG_DEBUG(("We do not support IV Included flag"));
2097     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2098   }
2099
2100   /* Check and select security properties */
2101   status = silc_ske_select_security_properties(ske, remote_payload,
2102                                                &ske->prop);
2103   if (status != SILC_SKE_STATUS_OK) {
2104     /** Error selecting proposal */
2105     silc_ske_payload_start_free(remote_payload);
2106     ske->status = status;
2107     silc_fsm_next(fsm, silc_ske_st_responder_error);
2108     return SILC_FSM_CONTINUE;
2109   }
2110
2111   silc_ske_payload_start_free(remote_payload);
2112
2113   /* Encode our reply payload to send the selected security properties */
2114   status = silc_ske_payload_start_encode(ske, ske->start_payload,
2115                                          &packet_buf);
2116   if (status != SILC_SKE_STATUS_OK)
2117     goto err;
2118
2119   /* Send the packet. */
2120   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2121                             silc_buffer_data(packet_buf),
2122                             silc_buffer_len(packet_buf)))
2123     goto err;
2124
2125   silc_buffer_free(packet_buf);
2126
2127   /** Waiting initiator's KE payload */
2128   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2129   return SILC_FSM_WAIT;
2130
2131  err:
2132   if (ske->prop->group)
2133     silc_ske_group_free(ske->prop->group);
2134   if (ske->prop->cipher)
2135     silc_cipher_free(ske->prop->cipher);
2136   if (ske->prop->hash)
2137     silc_hash_free(ske->prop->hash);
2138   if (ske->prop->hmac)
2139     silc_hmac_free(ske->prop->hmac);
2140   silc_free(ske->prop);
2141   ske->prop = NULL;
2142
2143   if (status == SILC_SKE_STATUS_OK)
2144     status = SILC_SKE_STATUS_ERROR;
2145
2146   /** Error */
2147   ske->status = status;
2148   silc_fsm_next(fsm, silc_ske_st_responder_error);
2149   return SILC_FSM_CONTINUE;
2150 }
2151
2152 /* Phase-2.  Decode initiator's KE payload */
2153
2154 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2155 {
2156   SilcSKE ske = fsm_context;
2157   SilcSKEStatus status;
2158   SilcSKEKEPayload recv_payload;
2159   SilcBuffer packet_buf = &ske->packet->buffer;
2160
2161   SILC_LOG_DEBUG(("Start"));
2162
2163   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2164     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2165     if (silc_ske_install_retransmission(ske)) {
2166       silc_packet_free(ske->packet);
2167       ske->packet = NULL;
2168       return SILC_FSM_WAIT;
2169     } else {
2170       silc_packet_free(ske->packet);
2171       ske->packet = NULL;
2172       ske->status = SILC_SKE_STATUS_ERROR;
2173       silc_fsm_next(fsm, silc_ske_st_responder_error);
2174       return SILC_FSM_CONTINUE;
2175     }
2176   }
2177
2178   /* Decode Key Exchange Payload */
2179   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2180   if (status != SILC_SKE_STATUS_OK) {
2181     /** Error decoding KE payload */
2182     silc_packet_free(ske->packet);
2183     ske->packet = NULL;
2184     ske->status = status;
2185     silc_fsm_next(fsm, silc_ske_st_responder_error);
2186     return SILC_FSM_CONTINUE;
2187   }
2188
2189   ske->ke1_payload = recv_payload;
2190
2191   silc_packet_free(ske->packet);
2192   ske->packet = NULL;
2193
2194   /* Verify public key, except in rekey, when it is not sent */
2195   if (!ske->rekey) {
2196     if (!recv_payload->pk_data) {
2197       /** Public key not provided */
2198       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2199                       "certificate), even though we require it"));
2200       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2201       silc_fsm_next(fsm, silc_ske_st_responder_error);
2202       return SILC_FSM_CONTINUE;
2203     }
2204
2205     /* Decode the remote's public key */
2206     if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2207                                     recv_payload->pk_data,
2208                                     recv_payload->pk_len,
2209                                     &ske->prop->public_key)) {
2210       /** Error decoding public key */
2211       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2212       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2213       silc_fsm_next(fsm, silc_ske_st_responder_error);
2214       return SILC_FSM_CONTINUE;
2215     }
2216
2217     SILC_LOG_DEBUG(("Verifying public key"));
2218
2219     /** Waiting public key verification */
2220     silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2221
2222     /* If repository is provided, verify the key from there. */
2223     if (ske->repository) {
2224       SilcSKRFind find;
2225
2226       find = silc_skr_find_alloc();
2227       if (!find) {
2228         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2229         silc_fsm_next(fsm, silc_ske_st_responder_error);
2230         return SILC_FSM_CONTINUE;
2231       }
2232       silc_skr_find_set_pkcs_type(find,
2233                                   silc_pkcs_get_type(ske->prop->public_key));
2234       silc_skr_find_set_public_key(find, ske->prop->public_key);
2235       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2236
2237       /* Find key from repository */
2238       SILC_FSM_CALL(silc_skr_find(ske->repository,
2239                                   silc_fsm_get_schedule(fsm), find,
2240                                   silc_ske_skr_callback, ske));
2241     } else {
2242       /* Verify from application */
2243       if (ske->callbacks->verify_key)
2244         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2245                                                  ske->callbacks->context,
2246                                                  silc_ske_pk_verified, NULL));
2247     }
2248   }
2249
2250   /** Generate KE2 payload */
2251   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2252   return SILC_FSM_CONTINUE;
2253 }
2254
2255 /* Phase-4. Generate KE2 payload */
2256
2257 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2258 {
2259   SilcSKE ske = fsm_context;
2260   SilcSKEStatus status;
2261   SilcSKEKEPayload recv_payload, send_payload = NULL;
2262   SilcMPInt *x = NULL, *KEY;
2263
2264   if (ske->aborted) {
2265     /** Aborted */
2266     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2267     return SILC_FSM_CONTINUE;
2268   }
2269
2270   /* Check result of public key verification */
2271   if (ske->status != SILC_SKE_STATUS_OK) {
2272     /** Public key not verified */
2273     SILC_LOG_DEBUG(("Public key verification failed"));
2274     goto err;
2275   }
2276
2277   recv_payload = ske->ke1_payload;
2278
2279   /* The public key verification was performed only if the Mutual
2280      Authentication flag is set. */
2281   if ((ske->start_payload &&
2282        ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) ||
2283       ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2284     unsigned char hash[SILC_HASH_MAXLEN];
2285     SilcUInt32 hash_len;
2286
2287     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2288
2289     /* Compute the hash value */
2290     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2291     if (status != SILC_SKE_STATUS_OK) {
2292       /** Error computing hash */
2293       SILC_LOG_DEBUG(("Error computing hash"));
2294       ske->status = status;
2295       goto err;
2296     }
2297
2298     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2299
2300     /* Verify signature */
2301     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2302                           recv_payload->sign_len, hash, hash_len, NULL)) {
2303       /** Incorrect signature */
2304       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2305       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2306       goto err;
2307     }
2308
2309     SILC_LOG_DEBUG(("Signature is Ok"));
2310
2311     memset(hash, 'F', hash_len);
2312   }
2313
2314   /* Create the random number x, 1 < x < q. */
2315   x = silc_calloc(1, sizeof(*x));
2316   if (!x) {
2317     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2318     goto err;
2319   }
2320   silc_mp_init(x);
2321   status =
2322     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2323                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2324                         x);
2325   if (status != SILC_SKE_STATUS_OK) {
2326     /** Error generating random number */
2327     ske->status = status;
2328     goto err;
2329   }
2330
2331   /* Save the results for later processing */
2332   send_payload = silc_calloc(1, sizeof(*send_payload));
2333   if (!send_payload) {
2334     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2335     goto err;
2336   }
2337   ske->x = x;
2338   ske->ke2_payload = send_payload;
2339
2340   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2341
2342   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2343   silc_mp_init(&send_payload->x);
2344   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2345                   &ske->prop->group->group);
2346
2347   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2348
2349   /* Compute the shared secret key */
2350   KEY = silc_calloc(1, sizeof(*KEY));
2351   if (!KEY) {
2352     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2353     goto err;
2354   }
2355   silc_mp_init(KEY);
2356   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2357                   &ske->prop->group->group);
2358   ske->KEY = KEY;
2359
2360   /** Send KE2 payload */
2361   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2362   return SILC_FSM_CONTINUE;
2363
2364  err:
2365   silc_mp_uninit(x);
2366   silc_free(x);
2367   ske->x = NULL;
2368   silc_free(send_payload);
2369   ske->ke2_payload = NULL;
2370
2371   silc_fsm_next(fsm, silc_ske_st_responder_error);
2372   return SILC_FSM_CONTINUE;
2373 }
2374
2375 /* Phase-5.  Send KE2 payload */
2376
2377 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2378 {
2379   SilcSKE ske = fsm_context;
2380   SilcSKEStatus status;
2381   SilcBuffer payload_buf;
2382   unsigned char hash[SILC_HASH_MAXLEN], sign[65536 + 1], *pk;
2383   SilcUInt32 hash_len, sign_len, pk_len;
2384
2385   SILC_LOG_DEBUG(("Start"));
2386
2387   if (ske->public_key && ske->private_key) {
2388     SILC_LOG_DEBUG(("Getting public key"));
2389
2390     /* Get the public key */
2391     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2392     if (!pk) {
2393       /** Error encoding public key */
2394       ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2395       silc_fsm_next(fsm, silc_ske_st_responder_error);
2396       return SILC_FSM_CONTINUE;
2397     }
2398     ske->ke2_payload->pk_data = pk;
2399     ske->ke2_payload->pk_len = pk_len;
2400   }
2401
2402   SILC_LOG_DEBUG(("Computing HASH value"));
2403
2404   /* Compute the hash value */
2405   memset(hash, 0, sizeof(hash));
2406   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2407   if (status != SILC_SKE_STATUS_OK) {
2408     /** Error computing hash */
2409     ske->status = status;
2410     silc_fsm_next(fsm, silc_ske_st_responder_error);
2411     return SILC_FSM_CONTINUE;
2412   }
2413   ske->hash = silc_memdup(hash, hash_len);
2414   if (!ske->hash) {
2415     /** Error computing hash */
2416     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2417     silc_fsm_next(fsm, silc_ske_st_responder_error);
2418     return SILC_FSM_CONTINUE;
2419   }
2420   ske->hash_len = hash_len;
2421
2422   if (ske->public_key && ske->private_key) {
2423     SILC_LOG_DEBUG(("Signing HASH value"));
2424
2425     /* Sign the hash value */
2426     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2427                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2428       /** Error computing signature */
2429       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2430       silc_fsm_next(fsm, silc_ske_st_responder_error);
2431       return SILC_FSM_CONTINUE;
2432     }
2433     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2434     if (!ske->ke2_payload->sign_data) {
2435       /** Error computing hash */
2436       ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2437       silc_fsm_next(fsm, silc_ske_st_responder_error);
2438       return SILC_FSM_CONTINUE;
2439     }
2440     ske->ke2_payload->sign_len = sign_len;
2441     memset(sign, 0, sizeof(sign));
2442   }
2443   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2444
2445   /* Encode the Key Exchange Payload */
2446   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2447                                       &payload_buf);
2448   if (status != SILC_SKE_STATUS_OK) {
2449     /** Error encoding KE payload */
2450     ske->status = status;
2451     silc_fsm_next(fsm, silc_ske_st_responder_error);
2452     return SILC_FSM_CONTINUE;
2453   }
2454
2455   /* Send the packet. */
2456   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2457                             payload_buf->data, silc_buffer_len(payload_buf))) {
2458     SILC_LOG_DEBUG(("Error sending packet"));
2459     ske->status = SILC_SKE_STATUS_ERROR;
2460     silc_fsm_next(fsm, silc_ske_st_responder_error);
2461     return SILC_FSM_CONTINUE;
2462   }
2463
2464   silc_buffer_free(payload_buf);
2465
2466   /* In case we are doing rekey move to finish it. */
2467   if (ske->rekey) {
2468     /** Finish rekey */
2469     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2470     return SILC_FSM_CONTINUE;
2471   }
2472
2473   if (!ske->no_acks) {
2474     /** Waiting completion */
2475     silc_fsm_next(fsm, silc_ske_st_responder_end);
2476     return SILC_FSM_WAIT;
2477   } else {
2478     /** Complete protocol */
2479     silc_fsm_next(fsm, silc_ske_st_responder_end);
2480     return SILC_FSM_CONTINUE;
2481   }
2482 }
2483
2484 /* Protocol completed */
2485
2486 SILC_FSM_STATE(silc_ske_st_responder_end)
2487 {
2488   SilcSKE ske = fsm_context;
2489   unsigned char tmp[4];
2490   SilcUInt32 hash_len, key_len, block_len;
2491
2492   if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
2493     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2494     if (silc_ske_install_retransmission(ske)) {
2495       silc_packet_free(ske->packet);
2496       ske->packet = NULL;
2497       return SILC_FSM_WAIT;
2498     } else {
2499       silc_packet_free(ske->packet);
2500       ske->packet = NULL;
2501       ske->status = SILC_SKE_STATUS_ERROR;
2502       silc_fsm_next(fsm, silc_ske_st_responder_error);
2503       return SILC_FSM_CONTINUE;
2504     }
2505   }
2506   if (ske->packet)
2507     silc_packet_free(ske->packet);
2508   ske->packet = NULL;
2509
2510   /* Process key material */
2511   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2512   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2513   hash_len = silc_hash_len(ske->prop->hash);
2514   ske->keymat = silc_ske_process_key_material(ske, block_len,
2515                                               key_len, hash_len,
2516                                               &ske->rekey);
2517   if (!ske->keymat) {
2518     /** Error processing key material */
2519     ske->status = SILC_SKE_STATUS_ERROR;
2520     silc_fsm_next(fsm, silc_ske_st_responder_error);
2521     return SILC_FSM_CONTINUE;
2522   }
2523
2524   if (!ske->no_acks) {
2525     /* Send SUCCESS packet */
2526     SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2527     silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2528   }
2529
2530   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2531   silc_schedule_task_del_by_context(ske->schedule, ske);
2532
2533   /* Call completion */
2534   silc_ske_completion(ske);
2535
2536   return SILC_FSM_FINISH;
2537 }
2538
2539 /* Aborted by application */
2540
2541 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2542 {
2543   SilcSKE ske = fsm_context;
2544   unsigned char tmp[4];
2545
2546   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2547
2548   /* Send FAILURE packet */
2549   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2550   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2551
2552   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2553   silc_schedule_task_del_by_context(ske->schedule, ske);
2554
2555   /* Call completion */
2556   silc_ske_completion(ske);
2557
2558   return SILC_FSM_FINISH;
2559 }
2560
2561 /* Failure received from remote */
2562
2563 SILC_FSM_STATE(silc_ske_st_responder_failure)
2564 {
2565   SilcSKE ske = fsm_context;
2566   SilcUInt32 error = ske->status;
2567
2568   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2569
2570   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2571     SILC_GET32_MSB(error, ske->packet->buffer.data);
2572     silc_packet_free(ske->packet);
2573     ske->packet = NULL;
2574   }
2575   if (error == SILC_SKE_STATUS_OK)
2576     error = SILC_SKE_STATUS_ERROR;
2577   ske->status = error;
2578
2579   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2580   silc_schedule_task_del_by_context(ske->schedule, ske);
2581
2582   /* Call completion */
2583   silc_ske_completion(ske);
2584
2585   return SILC_FSM_FINISH;
2586 }
2587
2588 /* Error occurred */
2589
2590 SILC_FSM_STATE(silc_ske_st_responder_error)
2591 {
2592   SilcSKE ske = fsm_context;
2593   unsigned char tmp[4];
2594   SilcUInt32 status;
2595
2596   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2597                   ske->status, silc_ske_map_status(ske->status)));
2598
2599   /* Send FAILURE packet */
2600   status = ske->status;
2601   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
2602     status = SILC_SKE_STATUS_ERROR;
2603   SILC_PUT32_MSB(status, tmp);
2604   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2605
2606   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2607   silc_schedule_task_del_by_context(ske->schedule, ske);
2608
2609   /* Call completion */
2610   silc_ske_completion(ske);
2611
2612   return SILC_FSM_FINISH;
2613 }
2614
2615 /* Starts the protocol as responder. */
2616
2617 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2618                                       SilcPacketStream stream,
2619                                       SilcSKEParams params)
2620 {
2621   SILC_LOG_DEBUG(("Start SKE as responder"));
2622
2623   if (!ske || !stream || !params || !params->version)
2624     return NULL;
2625
2626   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2627     return NULL;
2628
2629   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2630     return NULL;
2631
2632   ske->responder = TRUE;
2633   ske->flags = params->flags;
2634   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2635   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2636     ske->session_port = params->session_port;
2637   ske->version = params->version;
2638   ske->no_acks = params->no_acks;
2639   ske->prop = params->prop;
2640   if (!ske->version)
2641     return NULL;
2642   ++ske->refcnt;
2643
2644   /* Link to packet stream to get key exchange packets */
2645   ske->stream = stream;
2646   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2647                           SILC_PACKET_KEY_EXCHANGE,
2648                           SILC_PACKET_KEY_EXCHANGE_1,
2649                           SILC_PACKET_SUCCESS,
2650                           SILC_PACKET_FAILURE, -1);
2651
2652   /* Add key exchange timeout */
2653   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2654                                  ske, ske->timeout, 0);
2655
2656   /* Start SKE as responder */
2657   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2658
2659   return &ske->op;
2660 }
2661
2662 /***************************** Initiator Rekey ******************************/
2663
2664 /* Start rekey */
2665
2666 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2667 {
2668   SilcSKE ske = fsm_context;
2669   SilcStatus status;
2670
2671   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2672
2673   if (ske->aborted) {
2674     /** Aborted */
2675     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2676     return SILC_FSM_CONTINUE;
2677   }
2678
2679   /* Add rekey exchange timeout */
2680   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2681                                  ske, 30, 0);
2682
2683   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2684   if (!ske->prop) {
2685     /** No memory */
2686     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2687     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2688     return SILC_FSM_CONTINUE;
2689   }
2690
2691   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2692     /** Cannot allocate hash */
2693     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2694     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2695     return SILC_FSM_CONTINUE;
2696   }
2697
2698   /* Send REKEY packet to start rekey protocol */
2699   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2700     /** Error sending packet */
2701     SILC_LOG_DEBUG(("Error sending packet"));
2702     ske->status = SILC_SKE_STATUS_ERROR;
2703     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2704     return SILC_FSM_CONTINUE;
2705   }
2706
2707   /* If doing rekey without PFS, move directly to the end of the protocol. */
2708   if (!ske->rekey->pfs) {
2709     /** Rekey without PFS */
2710     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2711     return SILC_FSM_CONTINUE;
2712   }
2713
2714   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2715                                         &ske->prop->group);
2716   if (status != SILC_SKE_STATUS_OK) {
2717     /** Unknown group */
2718     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2719     return SILC_FSM_CONTINUE;
2720   }
2721
2722   /** Rekey with PFS */
2723   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2724   return SILC_FSM_CONTINUE;
2725 }
2726
2727 /* Sends REKEY_DONE packet to finish the protocol. */
2728
2729 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2730 {
2731   SilcSKE ske = fsm_context;
2732   SilcCipher send_key;
2733   SilcHmac hmac_send;
2734   SilcHash hash;
2735   SilcUInt32 key_len, block_len, hash_len, x_len;
2736   unsigned char *pfsbuf;
2737
2738   SILC_LOG_DEBUG(("Start"));
2739
2740   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2741   key_len = silc_cipher_get_key_len(send_key);
2742   block_len = silc_cipher_get_block_len(send_key);
2743   hash = ske->prop->hash;
2744   hash_len = silc_hash_len(hash);
2745
2746   /* Process key material */
2747   if (ske->rekey->pfs) {
2748     /* PFS */
2749     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2750     if (!pfsbuf) {
2751       SILC_LOG_ERROR(("Error processing key material"));
2752       silc_fsm_next(fsm, silc_ske_st_initiator_error);
2753       return SILC_FSM_CONTINUE;
2754     }
2755     ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2756                                                      block_len, key_len,
2757                                                      hash_len, hash);
2758     memset(pfsbuf, 0, x_len);
2759     silc_free(pfsbuf);
2760   } else {
2761     /* No PFS */
2762     ske->keymat =
2763       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2764                                          ske->rekey->enc_key_len / 8,
2765                                          block_len, key_len,
2766                                          hash_len, hash);
2767   }
2768
2769   if (!ske->keymat) {
2770     SILC_LOG_ERROR(("Error processing key material"));
2771     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2772     return SILC_FSM_CONTINUE;
2773   }
2774
2775   ske->prop->cipher = send_key;
2776   ske->prop->hmac = hmac_send;
2777
2778   /* Get sending keys */
2779   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2780                          &hmac_send, NULL, NULL)) {
2781     /** Cannot get keys */
2782     ske->status = SILC_SKE_STATUS_ERROR;
2783     ske->prop->cipher = NULL;
2784     ske->prop->hmac = NULL;
2785     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2786     return SILC_FSM_CONTINUE;
2787   }
2788
2789   ske->prop->cipher = NULL;
2790   ske->prop->hmac = NULL;
2791
2792   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2793      packet sent after this call will be protected with the new keys. */
2794   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2795                             TRUE)) {
2796     /** Cannot set keys */
2797     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2798     ske->status = SILC_SKE_STATUS_ERROR;
2799     silc_cipher_free(send_key);
2800     silc_hmac_free(hmac_send);
2801     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2802     return SILC_FSM_CONTINUE;
2803   }
2804
2805   /** Wait for REKEY_DONE */
2806   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2807   return SILC_FSM_WAIT;
2808 }
2809
2810 /* Rekey protocol end */
2811
2812 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2813 {
2814   SilcSKE ske = fsm_context;
2815   SilcCipher receive_key;
2816   SilcHmac hmac_receive;
2817   SilcSKERekeyMaterial rekey;
2818
2819   SILC_LOG_DEBUG(("Start"));
2820
2821   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2822     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2823     silc_packet_free(ske->packet);
2824     ske->packet = NULL;
2825     return SILC_FSM_WAIT;
2826   }
2827
2828   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2829   ske->prop->cipher = receive_key;
2830   ske->prop->hmac = hmac_receive;
2831
2832   /* Get receiving keys */
2833   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2834                          NULL, &hmac_receive, NULL)) {
2835     /** Cannot get keys */
2836     ske->status = SILC_SKE_STATUS_ERROR;
2837     ske->prop->cipher = NULL;
2838     ske->prop->hmac = NULL;
2839     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2840     return SILC_FSM_CONTINUE;
2841   }
2842
2843   /* Set new receiving keys into use.  All packets received after this will
2844      be decrypted with the new keys. */
2845   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2846                             hmac_receive, FALSE)) {
2847     /** Cannot set keys */
2848     SILC_LOG_DEBUG(("Cannot set new keys"));
2849     ske->status = SILC_SKE_STATUS_ERROR;
2850     silc_cipher_free(receive_key);
2851     silc_hmac_free(hmac_receive);
2852     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2853     return SILC_FSM_CONTINUE;
2854   }
2855
2856   SILC_LOG_DEBUG(("Rekey completed successfully"));
2857
2858   /* Generate new rekey material */
2859   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2860   if (!rekey) {
2861     /** No memory */
2862     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2863     ske->prop->cipher = NULL;
2864     ske->prop->hmac = NULL;
2865     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2866     return SILC_FSM_CONTINUE;
2867   }
2868   rekey->pfs = ske->rekey->pfs;
2869   ske->rekey = rekey;
2870
2871   ske->prop->cipher = NULL;
2872   ske->prop->hmac = NULL;
2873   silc_packet_free(ske->packet);
2874   ske->packet = NULL;
2875   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2876   silc_schedule_task_del_by_context(ske->schedule, ske);
2877
2878   /* Call completion */
2879   silc_ske_completion(ske);
2880
2881   return SILC_FSM_FINISH;
2882 }
2883
2884 /* Starts rekey protocol as initiator */
2885
2886 SilcAsyncOperation
2887 silc_ske_rekey_initiator(SilcSKE ske,
2888                          SilcPacketStream stream,
2889                          SilcSKERekeyMaterial rekey)
2890 {
2891   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2892
2893   if (!ske || !stream || !rekey) {
2894     SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2895     SILC_ASSERT(rekey);
2896     return NULL;
2897   }
2898
2899   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2900     return NULL;
2901
2902   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2903     return NULL;
2904
2905   ske->rekey = rekey;
2906   ske->responder = FALSE;
2907   ske->rekeying = TRUE;
2908   ++ske->refcnt;
2909
2910   /* Link to packet stream to get key exchange packets */
2911   ske->stream = stream;
2912   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2913                           SILC_PACKET_REKEY,
2914                           SILC_PACKET_REKEY_DONE,
2915                           SILC_PACKET_KEY_EXCHANGE_2,
2916                           SILC_PACKET_SUCCESS,
2917                           SILC_PACKET_FAILURE, -1);
2918
2919   /* Start SKE rekey as initiator */
2920   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2921
2922   return &ske->op;
2923 }
2924
2925 /***************************** Responder Rekey ******************************/
2926
2927 /* Wait for initiator's packet */
2928
2929 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2930 {
2931   SilcSKE ske = fsm_context;
2932
2933   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2934
2935   if (ske->aborted) {
2936     /** Aborted */
2937     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2938     return SILC_FSM_CONTINUE;
2939   }
2940
2941   /* Add rekey exchange timeout */
2942   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2943                                  ske, 30, 0);
2944
2945   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2946
2947   /* If REKEY packet already received process it directly */
2948   if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2949     return SILC_FSM_CONTINUE;
2950
2951   /* Wait for REKEY */
2952   return SILC_FSM_WAIT;
2953 }
2954
2955 /* Process initiator's REKEY packet */
2956
2957 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2958 {
2959   SilcSKE ske = fsm_context;
2960   SilcSKEStatus status;
2961
2962   SILC_LOG_DEBUG(("Start"));
2963
2964   if (ske->packet->type != SILC_PACKET_REKEY) {
2965     ske->status = SILC_SKE_STATUS_ERROR;
2966     silc_packet_free(ske->packet);
2967     ske->packet = NULL;
2968     silc_fsm_next(fsm, silc_ske_st_responder_error);
2969     return SILC_FSM_CONTINUE;
2970   }
2971
2972   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2973   if (!ske->prop) {
2974     /** No memory */
2975     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2976     silc_fsm_next(fsm, silc_ske_st_responder_error);
2977     return SILC_FSM_CONTINUE;
2978   }
2979
2980   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2981     /** Cannot allocate hash */
2982     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2983     silc_fsm_next(fsm, silc_ske_st_responder_error);
2984     return SILC_FSM_CONTINUE;
2985   }
2986
2987   /* If doing rekey without PFS, move directly to the end of the protocol. */
2988   if (!ske->rekey->pfs) {
2989     /** Rekey without PFS */
2990     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2991     return SILC_FSM_CONTINUE;
2992   }
2993
2994   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2995                                         &ske->prop->group);
2996   if (status != SILC_SKE_STATUS_OK) {
2997     /** Unknown group */
2998     silc_fsm_next(fsm, silc_ske_st_responder_error);
2999     return SILC_FSM_CONTINUE;
3000   }
3001
3002   /** Rekey with PFS */
3003   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
3004   return SILC_FSM_WAIT;
3005 }
3006
3007 /* Sends REKEY_DONE packet to finish the protocol. */
3008
3009 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
3010 {
3011   SilcSKE ske = fsm_context;
3012   SilcCipher send_key;
3013   SilcHmac hmac_send;
3014   SilcHash hash;
3015   SilcUInt32 key_len, block_len, hash_len, x_len;
3016   unsigned char *pfsbuf;
3017
3018   SILC_LOG_DEBUG(("Start"));
3019
3020   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
3021   key_len = silc_cipher_get_key_len(send_key);
3022   block_len = silc_cipher_get_block_len(send_key);
3023   hash = ske->prop->hash;
3024   hash_len = silc_hash_len(hash);
3025
3026   /* Process key material */
3027   if (ske->rekey->pfs) {
3028     /* PFS */
3029     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
3030     if (!pfsbuf) {
3031       SILC_LOG_ERROR(("Error processing key material"));
3032       silc_fsm_next(fsm, silc_ske_st_responder_error);
3033       return SILC_FSM_CONTINUE;
3034     }
3035     ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
3036                                                      block_len, key_len,
3037                                                      hash_len, hash);
3038     memset(pfsbuf, 0, x_len);
3039     silc_free(pfsbuf);
3040   } else {
3041     /* No PFS */
3042     ske->keymat =
3043       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
3044                                          ske->rekey->enc_key_len / 8,
3045                                          block_len, key_len,
3046                                          hash_len, hash);
3047   }
3048
3049   if (!ske->keymat) {
3050     SILC_LOG_ERROR(("Error processing key material"));
3051     silc_fsm_next(fsm, silc_ske_st_responder_error);
3052     return SILC_FSM_CONTINUE;
3053   }
3054
3055   ske->prop->cipher = send_key;
3056   ske->prop->hmac = hmac_send;
3057
3058   /* Get sending keys */
3059   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
3060                          &hmac_send, NULL, NULL)) {
3061     /** Cannot get keys */
3062     ske->status = SILC_SKE_STATUS_ERROR;
3063     ske->prop->cipher = NULL;
3064     ske->prop->hmac = NULL;
3065     silc_fsm_next(fsm, silc_ske_st_responder_error);
3066     return SILC_FSM_CONTINUE;
3067   }
3068
3069   ske->prop->cipher = NULL;
3070   ske->prop->hmac = NULL;
3071
3072   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
3073      packet sent after this call will be protected with the new keys. */
3074   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
3075                             TRUE)) {
3076     /** Cannot set keys */
3077     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
3078     ske->status = SILC_SKE_STATUS_ERROR;
3079     silc_cipher_free(send_key);
3080     silc_hmac_free(hmac_send);
3081     silc_fsm_next(fsm, silc_ske_st_responder_error);
3082     return SILC_FSM_CONTINUE;
3083   }
3084
3085   /** Wait for REKEY_DONE */
3086   silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
3087   return SILC_FSM_WAIT;
3088 }
3089
3090 /* Rekey protocol end */
3091
3092 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
3093 {
3094   SilcSKE ske = fsm_context;
3095   SilcCipher receive_key;
3096   SilcHmac hmac_receive;
3097   SilcSKERekeyMaterial rekey;
3098
3099   SILC_LOG_DEBUG(("Start"));
3100
3101   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
3102     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
3103     silc_packet_free(ske->packet);
3104     ske->packet = NULL;
3105     return SILC_FSM_WAIT;
3106   }
3107
3108   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
3109   ske->prop->cipher = receive_key;
3110   ske->prop->hmac = hmac_receive;
3111
3112   /* Get receiving keys */
3113   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3114                          NULL, &hmac_receive, NULL)) {
3115     /** Cannot get keys */
3116     ske->status = SILC_SKE_STATUS_ERROR;
3117     ske->prop->cipher = NULL;
3118     ske->prop->hmac = NULL;
3119     silc_fsm_next(fsm, silc_ske_st_responder_error);
3120     return SILC_FSM_CONTINUE;
3121   }
3122
3123   /* Set new receiving keys into use.  All packets received after this will
3124      be decrypted with the new keys. */
3125   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3126                             hmac_receive, FALSE)) {
3127     /** Cannot set keys */
3128     SILC_LOG_DEBUG(("Cannot set new keys"));
3129     ske->status = SILC_SKE_STATUS_ERROR;
3130     ske->prop->cipher = NULL;
3131     ske->prop->hmac = NULL;
3132     silc_cipher_free(receive_key);
3133     silc_hmac_free(hmac_receive);
3134     silc_fsm_next(fsm, silc_ske_st_responder_error);
3135     return SILC_FSM_CONTINUE;
3136   }
3137
3138   SILC_LOG_DEBUG(("Rekey completed successfully"));
3139
3140   /* Generate new rekey material */
3141   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3142   if (!rekey) {
3143     /** No memory */
3144     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3145     ske->prop->cipher = NULL;
3146     ske->prop->hmac = NULL;
3147     silc_fsm_next(fsm, silc_ske_st_responder_error);
3148     return SILC_FSM_CONTINUE;
3149   }
3150   rekey->pfs = ske->rekey->pfs;
3151   ske->rekey = rekey;
3152
3153   ske->prop->cipher = NULL;
3154   ske->prop->hmac = NULL;
3155   silc_packet_free(ske->packet);
3156   ske->packet = NULL;
3157   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3158   silc_schedule_task_del_by_context(ske->schedule, ske);
3159
3160   /* Call completion */
3161   silc_ske_completion(ske);
3162
3163   return SILC_FSM_FINISH;
3164 }
3165
3166 /* Starts rekey protocol as responder */
3167
3168 SilcAsyncOperation
3169 silc_ske_rekey_responder(SilcSKE ske,
3170                          SilcPacketStream stream,
3171                          SilcSKERekeyMaterial rekey,
3172                          SilcPacket packet)
3173 {
3174   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3175
3176   if (!ske || !stream || !rekey)
3177     return NULL;
3178
3179   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3180     return NULL;
3181
3182   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3183     return NULL;
3184
3185   ske->rekey = rekey;
3186   ske->responder = TRUE;
3187   ske->rekeying = TRUE;
3188   ske->packet = packet;
3189   ++ske->refcnt;
3190
3191   /* Link to packet stream to get key exchange packets */
3192   ske->stream = stream;
3193   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3194                           SILC_PACKET_REKEY,
3195                           SILC_PACKET_REKEY_DONE,
3196                           SILC_PACKET_KEY_EXCHANGE_1,
3197                           SILC_PACKET_SUCCESS,
3198                           SILC_PACKET_FAILURE, -1);
3199
3200   /* Start SKE rekey as responder */
3201   silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3202
3203   return &ske->op;
3204 }
3205
3206 /* Processes the provided key material `data' as the SILC protocol
3207    specification defines. */
3208
3209 SilcSKEKeyMaterial
3210 silc_ske_process_key_material_data(unsigned char *data,
3211                                    SilcUInt32 data_len,
3212                                    SilcUInt32 req_iv_len,
3213                                    SilcUInt32 req_enc_key_len,
3214                                    SilcUInt32 req_hmac_key_len,
3215                                    SilcHash hash)
3216 {
3217   SilcBuffer buf;
3218   unsigned char hashd[SILC_HASH_MAXLEN];
3219   SilcUInt32 hash_len = req_hmac_key_len;
3220   SilcUInt32 enc_key_len = req_enc_key_len / 8;
3221   SilcSKEKeyMaterial key;
3222
3223   SILC_LOG_DEBUG(("Start"));
3224
3225   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3226     return NULL;
3227
3228   key = silc_calloc(1, sizeof(*key));
3229   if (!key)
3230     return NULL;
3231
3232   buf = silc_buffer_alloc_size(1 + data_len);
3233   if (!buf)
3234     return NULL;
3235   silc_buffer_format(buf,
3236                      SILC_STR_UI_CHAR(0),
3237                      SILC_STR_DATA(data, data_len),
3238                      SILC_STR_END);
3239
3240   /* Take IVs */
3241   memset(hashd, 0, sizeof(hashd));
3242   buf->data[0] = 0;
3243   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3244   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3245   if (!key->send_iv) {
3246     silc_buffer_clear(buf);
3247     silc_buffer_free(buf);
3248     silc_free(key);
3249     return NULL;
3250   }
3251   memcpy(key->send_iv, hashd, req_iv_len);
3252   memset(hashd, 0, sizeof(hashd));
3253   buf->data[0] = 1;
3254   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3255   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3256   if (!key->receive_iv) {
3257     silc_buffer_clear(buf);
3258     silc_buffer_free(buf);
3259     silc_free(key);
3260     return NULL;
3261   }
3262   memcpy(key->receive_iv, hashd, req_iv_len);
3263   key->iv_len = req_iv_len;
3264
3265   /* Take the encryption keys. If requested key size is more than
3266      the size of hash length we will distribute more key material
3267      as protocol defines. */
3268   buf->data[0] = 2;
3269   if (enc_key_len > hash_len) {
3270     SilcBuffer dist;
3271     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3272         k3[SILC_HASH_MAXLEN];
3273     unsigned char *dtmp;
3274
3275     /* XXX */
3276     if (enc_key_len > (3 * hash_len))
3277       return NULL;
3278
3279     /* Take first round */
3280     memset(k1, 0, sizeof(k1));
3281     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3282
3283     /* Take second round */
3284     dist = silc_buffer_alloc_size(data_len + hash_len);
3285     if (!dist)
3286       return NULL;
3287     silc_buffer_format(dist,
3288                        SILC_STR_DATA(data, data_len),
3289                        SILC_STR_DATA(k1, hash_len),
3290                        SILC_STR_END);
3291     memset(k2, 0, sizeof(k2));
3292     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3293
3294     /* Take third round */
3295     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3296     silc_buffer_pull_tail(dist, hash_len);
3297     silc_buffer_pull(dist, data_len + hash_len);
3298     silc_buffer_format(dist,
3299                        SILC_STR_DATA(k2, hash_len),
3300                        SILC_STR_END);
3301     silc_buffer_push(dist, data_len + hash_len);
3302     memset(k3, 0, sizeof(k3));
3303     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3304
3305     /* Then, save the keys */
3306     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3307     if (!dtmp) {
3308       silc_buffer_clear(buf);
3309       silc_buffer_free(buf);
3310       silc_free(key);
3311       return NULL;
3312     }
3313     memcpy(dtmp, k1, hash_len);
3314     memcpy(dtmp + hash_len, k2, hash_len);
3315     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3316
3317     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3318     if (!key->send_enc_key) {
3319       silc_buffer_clear(buf);
3320       silc_buffer_free(buf);
3321       silc_free(key);
3322       silc_free(dtmp);
3323       return NULL;
3324     }
3325     memcpy(key->send_enc_key, dtmp, enc_key_len);
3326     key->enc_key_len = req_enc_key_len;
3327
3328     memset(dtmp, 0, (3 * hash_len));
3329     memset(k1, 0, sizeof(k1));
3330     memset(k2, 0, sizeof(k2));
3331     memset(k3, 0, sizeof(k3));
3332     silc_free(dtmp);
3333     silc_buffer_clear(dist);
3334     silc_buffer_free(dist);
3335   } else {
3336     /* Take normal hash as key */
3337     memset(hashd, 0, sizeof(hashd));
3338     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3339     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3340     if (!key->send_enc_key) {
3341       silc_buffer_clear(buf);
3342       silc_buffer_free(buf);
3343       silc_free(key);
3344       return NULL;
3345     }
3346     memcpy(key->send_enc_key, hashd, enc_key_len);
3347     key->enc_key_len = req_enc_key_len;
3348   }
3349
3350   buf->data[0] = 3;
3351   if (enc_key_len > hash_len) {
3352     SilcBuffer dist;
3353     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3354         k3[SILC_HASH_MAXLEN];
3355     unsigned char *dtmp;
3356
3357     /* XXX */
3358     if (enc_key_len > (3 * hash_len))
3359       return NULL;
3360
3361     /* Take first round */
3362     memset(k1, 0, sizeof(k1));
3363     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3364
3365     /* Take second round */
3366     dist = silc_buffer_alloc_size(data_len + hash_len);
3367     if (!dist)
3368       return NULL;
3369     silc_buffer_format(dist,
3370                        SILC_STR_DATA(data, data_len),
3371                        SILC_STR_DATA(k1, hash_len),
3372                        SILC_STR_END);
3373     memset(k2, 0, sizeof(k2));
3374     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3375
3376     /* Take third round */
3377     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3378     silc_buffer_pull_tail(dist, hash_len);
3379     silc_buffer_pull(dist, data_len + hash_len);
3380     silc_buffer_format(dist,
3381                        SILC_STR_DATA(k2, hash_len),
3382                        SILC_STR_END);
3383     silc_buffer_push(dist, data_len + hash_len);
3384     memset(k3, 0, sizeof(k3));
3385     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3386
3387     /* Then, save the keys */
3388     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3389     if (!dtmp) {
3390       silc_buffer_clear(buf);
3391       silc_buffer_free(buf);
3392       silc_free(key);
3393       return NULL;
3394     }
3395     memcpy(dtmp, k1, hash_len);
3396     memcpy(dtmp + hash_len, k2, hash_len);
3397     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3398
3399     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3400     if (!key->receive_enc_key) {
3401       silc_buffer_clear(buf);
3402       silc_buffer_free(buf);
3403       silc_free(key);
3404       silc_free(dtmp);
3405       return NULL;
3406     }
3407     memcpy(key->receive_enc_key, dtmp, enc_key_len);
3408     key->enc_key_len = req_enc_key_len;
3409
3410     memset(dtmp, 0, (3 * hash_len));
3411     memset(k1, 0, sizeof(k1));
3412     memset(k2, 0, sizeof(k2));
3413     memset(k3, 0, sizeof(k3));
3414     silc_free(dtmp);
3415     silc_buffer_clear(dist);
3416     silc_buffer_free(dist);
3417   } else {
3418     /* Take normal hash as key */
3419     memset(hashd, 0, sizeof(hashd));
3420     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3421     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3422     if (!key->receive_enc_key) {
3423       silc_buffer_clear(buf);
3424       silc_buffer_free(buf);
3425       silc_free(key);
3426       return NULL;
3427     }
3428     memcpy(key->receive_enc_key, hashd, enc_key_len);
3429     key->enc_key_len = req_enc_key_len;
3430   }
3431
3432   /* Take HMAC keys */
3433   memset(hashd, 0, sizeof(hashd));
3434   buf->data[0] = 4;
3435   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3436   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3437   if (!key->send_hmac_key) {
3438     silc_buffer_clear(buf);
3439     silc_buffer_free(buf);
3440     silc_free(key);
3441     return NULL;
3442   }
3443   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3444   memset(hashd, 0, sizeof(hashd));
3445   buf->data[0] = 5;
3446   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3447   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3448   if (!key->receive_hmac_key) {
3449     silc_buffer_clear(buf);
3450     silc_buffer_free(buf);
3451     silc_free(key);
3452     return NULL;
3453   }
3454   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3455   key->hmac_key_len = req_hmac_key_len;
3456   memset(hashd, 0, sizeof(hashd));
3457
3458   silc_buffer_clear(buf);
3459   silc_buffer_free(buf);
3460
3461   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3462
3463   return key;
3464 }
3465
3466 /* Processes negotiated key material as protocol specifies. This returns
3467    the actual keys to be used in the SILC. */
3468
3469 SilcSKEKeyMaterial
3470 silc_ske_process_key_material(SilcSKE ske,
3471                               SilcUInt32 req_iv_len,
3472                               SilcUInt32 req_enc_key_len,
3473                               SilcUInt32 req_hmac_key_len,
3474                               SilcSKERekeyMaterial *rekey)
3475 {
3476   SilcBuffer buf;
3477   unsigned char *tmpbuf;
3478   SilcUInt32 klen;
3479   SilcSKEKeyMaterial key;
3480
3481   /* Encode KEY to binary data */
3482   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3483
3484   buf = silc_buffer_alloc_size(klen + ske->hash_len);
3485   if (!buf)
3486     return NULL;
3487   silc_buffer_format(buf,
3488                      SILC_STR_DATA(tmpbuf, klen),
3489                      SILC_STR_DATA(ske->hash, ske->hash_len),
3490                      SILC_STR_END);
3491
3492   /* Process the key material */
3493   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3494                                            req_iv_len, req_enc_key_len,
3495                                            req_hmac_key_len,
3496                                            ske->prop->hash);
3497
3498   memset(tmpbuf, 0, klen);
3499   silc_free(tmpbuf);
3500   silc_buffer_clear(buf);
3501   silc_buffer_free(buf);
3502
3503   if (rekey) {
3504     *rekey = silc_ske_make_rekey_material(ske, key);
3505     if (!(*rekey))
3506       return NULL;
3507   }
3508
3509   return key;
3510 }
3511
3512 /* Free key material structure */
3513
3514 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3515 {
3516   if (!key)
3517     return;
3518
3519   if (key->send_iv)
3520     silc_free(key->send_iv);
3521   if (key->receive_iv)
3522     silc_free(key->receive_iv);
3523   if (key->send_enc_key) {
3524     memset(key->send_enc_key, 0, key->enc_key_len / 8);
3525     silc_free(key->send_enc_key);
3526   }
3527   if (key->receive_enc_key) {
3528     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3529     silc_free(key->receive_enc_key);
3530   }
3531   if (key->send_hmac_key) {
3532     memset(key->send_hmac_key, 0, key->hmac_key_len);
3533     silc_free(key->send_hmac_key);
3534   }
3535   if (key->receive_hmac_key) {
3536     memset(key->receive_hmac_key, 0, key->hmac_key_len);
3537     silc_free(key->receive_hmac_key);
3538   }
3539   silc_free(key);
3540 }
3541
3542 /* Free rekey material */
3543
3544 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3545 {
3546   if (!rekey)
3547     return;
3548   if (rekey->send_enc_key) {
3549     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3550     silc_free(rekey->send_enc_key);
3551   }
3552   silc_free(rekey->hash);
3553   silc_free(rekey);
3554 }
3555
3556 /* Set keys into use */
3557
3558 SilcBool silc_ske_set_keys(SilcSKE ske,
3559                            SilcSKEKeyMaterial keymat,
3560                            SilcSKESecurityProperties prop,
3561                            SilcCipher *ret_send_key,
3562                            SilcCipher *ret_receive_key,
3563                            SilcHmac *ret_hmac_send,
3564                            SilcHmac *ret_hmac_receive,
3565                            SilcHash *ret_hash)
3566 {
3567   unsigned char iv[SILC_HASH_MAXLEN];
3568   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3569
3570   /* Allocate ciphers to be used in the communication */
3571   if (ret_send_key) {
3572     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3573                            ret_send_key))
3574       return FALSE;
3575   }
3576   if (ret_receive_key) {
3577     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3578                            ret_receive_key))
3579       return FALSE;
3580   }
3581
3582   /* Allocate HMACs */
3583   if (ret_hmac_send) {
3584     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3585                          ret_hmac_send))
3586       return FALSE;
3587   }
3588   if (ret_hmac_receive) {
3589     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3590                          ret_hmac_receive))
3591       return FALSE;
3592   }
3593
3594   /* Allocate hash */
3595   if (ret_hash) {
3596     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3597       return FALSE;
3598   }
3599
3600   /* Set key material */
3601   memset(iv, 0, sizeof(iv));
3602   if (ske->responder) {
3603     if (ret_send_key) {
3604       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3605                           keymat->enc_key_len, TRUE);
3606
3607       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3608         /* Counter mode */
3609         if (!ske->rekeying) {
3610           /* Set IV. */
3611           memcpy(iv, ske->hash, 4);
3612           if (!iv_included)
3613             memcpy(iv + 4, keymat->receive_iv, 8);
3614         } else {
3615           /* Rekey, recompute the truncated hash value. */
3616           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3617           if (!iv_included)
3618             memcpy(iv + 4, keymat->receive_iv, 8);
3619           else
3620             memset(iv + 4, 0, 12);
3621         }
3622
3623         silc_cipher_set_iv(*ret_send_key, iv);
3624       } else {
3625         /* Other modes */
3626         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3627       }
3628     }
3629     if (ret_receive_key) {
3630       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3631                           keymat->enc_key_len, FALSE);
3632
3633       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3634         /* Counter mode */
3635         if (!ske->rekeying) {
3636           /* Set IV. */
3637           memcpy(iv, ske->hash, 4);
3638           if (!iv_included)
3639             memcpy(iv + 4, keymat->send_iv, 8);
3640         } else {
3641           /* Rekey, recompute the truncated hash value. */
3642           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3643           if (!iv_included)
3644             memcpy(iv + 4, keymat->send_iv, 8);
3645           else
3646             memset(iv + 4, 0, 12);
3647         }
3648
3649         silc_cipher_set_iv(*ret_receive_key, iv);
3650       } else {
3651         /* Other modes */
3652         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3653       }
3654     }
3655     if (ret_hmac_send)
3656       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3657                         keymat->hmac_key_len);
3658     if (ret_hmac_receive)
3659       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3660                         keymat->hmac_key_len);
3661   } else {
3662     if (ret_send_key) {
3663       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3664                           keymat->enc_key_len, TRUE);
3665
3666       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3667         /* Counter mode */
3668         if (!ske->rekeying) {
3669           /* Set IV. */
3670           memcpy(iv, ske->hash, 4);
3671           if (!iv_included)
3672             memcpy(iv + 4, keymat->send_iv, 8);
3673         } else {
3674           /* Rekey, recompute the truncated hash value. */
3675           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3676           if (!iv_included)
3677             memcpy(iv + 4, keymat->send_iv, 8);
3678           else
3679             memset(iv + 4, 0, 12);
3680         }
3681
3682         silc_cipher_set_iv(*ret_send_key, iv);
3683       } else {
3684         /* Other modes */
3685         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3686       }
3687     }
3688     if (ret_receive_key) {
3689       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3690                           keymat->enc_key_len, FALSE);
3691
3692       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3693         /* Counter mode */
3694         if (!ske->rekeying) {
3695           /* Set IV.  If IV Included flag was negotiated we only set the
3696              truncated hash value. */
3697           memcpy(iv, ske->hash, 4);
3698           if (!iv_included)
3699             memcpy(iv + 4, keymat->receive_iv, 8);
3700         } else {
3701           /* Rekey, recompute the truncated hash value. */
3702           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3703           if (!iv_included)
3704             memcpy(iv + 4, keymat->receive_iv, 8);
3705           else
3706             memset(iv + 4, 0, 12);
3707         }
3708
3709         silc_cipher_set_iv(*ret_receive_key, iv);
3710       } else {
3711         /* Other modes */
3712         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3713       }
3714     }
3715     if (ret_hmac_send)
3716       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3717                         keymat->hmac_key_len);
3718     if (ret_hmac_receive)
3719       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3720                         keymat->hmac_key_len);
3721   }
3722
3723   return TRUE;
3724 }
3725
3726 const char *silc_ske_status_string[] =
3727 {
3728   /* Official */
3729   "Ok",
3730   "Unexpected error occurred",
3731   "Bad payload in packet",
3732   "Unsupported group",
3733   "Unsupported cipher",
3734   "Unsupported PKCS",
3735   "Unsupported hash function",
3736   "Unsupported HMAC",
3737   "Public key not accepted",
3738   "Incorrect signature",
3739   "Bad or unsupported version",
3740   "Invalid cookie",
3741
3742   /* Other errors */
3743   "Remote did not provide public key",
3744   "Bad reserved field in packet",
3745   "Bad payload length in packet",
3746   "Error computing signature",
3747   "System out of memory",
3748   "Key exchange timeout",
3749   "Key exchange timeout",
3750
3751   NULL
3752 };
3753
3754 /* Maps status to readable string and returns the string. If string is not
3755    found and empty character string ("") is returned. */
3756
3757 const char *silc_ske_map_status(SilcSKEStatus status)
3758 {
3759   int i;
3760
3761   for (i = 0; silc_ske_status_string[i]; i++)
3762     if (status == i)
3763       return silc_ske_status_string[i];
3764
3765   return "";
3766 }
3767
3768 /* Parses remote host's version string. */
3769
3770 SilcBool silc_ske_parse_version(SilcSKE ske,
3771                                 SilcUInt32 *protocol_version,
3772                                 char **protocol_version_string,
3773                                 SilcUInt32 *software_version,
3774                                 char **software_version_string,
3775                                 char **vendor_version)
3776 {
3777   return silc_parse_version_string(ske->remote_version,
3778                                    protocol_version,
3779                                    protocol_version_string,
3780                                    software_version,
3781                                    software_version_string,
3782                                    vendor_version);
3783 }
3784
3785 /* Get security properties */
3786
3787 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3788 {
3789   return ske->prop;
3790 }
3791
3792 /* Get key material */
3793
3794 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3795 {
3796   return ske->keymat;
3797 }