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