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