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