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