a4822e95a505a8cb709d6d63bfb0f4eabf9e8f0f
[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 = %lu)",
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     ske->status = error;
1813     silc_packet_free(ske->packet);
1814     ske->packet = NULL;
1815   }
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     ske->status = error;
2387     silc_packet_free(ske->packet);
2388     ske->packet = NULL;
2389   }
2390
2391   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2392   silc_schedule_task_del_by_context(ske->schedule, ske);
2393
2394   /* Call completion */
2395   silc_ske_completion(ske);
2396
2397   return SILC_FSM_FINISH;
2398 }
2399
2400 /* Error occurred */
2401
2402 SILC_FSM_STATE(silc_ske_st_responder_error)
2403 {
2404   SilcSKE ske = fsm_context;
2405   unsigned char tmp[4];
2406
2407   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2408                   ske->status, silc_ske_map_status(ske->status)));
2409
2410   /* Send FAILURE packet */
2411   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2412     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2413   SILC_PUT32_MSB(ske->status, tmp);
2414   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2415
2416   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2417   silc_schedule_task_del_by_context(ske->schedule, ske);
2418
2419   /* Call completion */
2420   silc_ske_completion(ske);
2421
2422   return SILC_FSM_FINISH;
2423 }
2424
2425 /* Starts the protocol as responder. */
2426
2427 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2428                                       SilcPacketStream stream,
2429                                       SilcSKEParams params)
2430 {
2431   SILC_LOG_DEBUG(("Start SKE as responder"));
2432
2433   if (!ske || !stream || !params || !params->version)
2434     return NULL;
2435
2436   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2437     return NULL;
2438
2439   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2440     return NULL;
2441
2442   ske->responder = TRUE;
2443   ske->flags = params->flags;
2444   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2445   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2446     ske->session_port = params->session_port;
2447   ske->version = params->version;
2448   if (!ske->version)
2449     return NULL;
2450   ++ ske->refcnt;
2451
2452   /* Link to packet stream to get key exchange packets */
2453   ske->stream = stream;
2454   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2455                           SILC_PACKET_KEY_EXCHANGE,
2456                           SILC_PACKET_KEY_EXCHANGE_1,
2457                           SILC_PACKET_SUCCESS,
2458                           SILC_PACKET_FAILURE, -1);
2459
2460   /* Start SKE as responder */
2461   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2462
2463   return &ske->op;
2464 }
2465
2466 /***************************** Initiator Rekey ******************************/
2467
2468 /* Start rekey */
2469
2470 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2471 {
2472   SilcSKE ske = fsm_context;
2473   SilcStatus status;
2474
2475   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2476
2477   if (ske->aborted) {
2478     /** Aborted */
2479     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2480     return SILC_FSM_CONTINUE;
2481   }
2482
2483   /* Add rekey exchange timeout */
2484   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2485                                  ske, 30, 0);
2486
2487   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2488   if (!ske->prop) {
2489     /** No memory */
2490     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2491     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2492     return SILC_FSM_CONTINUE;
2493   }
2494
2495   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2496     /** Cannot allocate hash */
2497     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2498     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2499     return SILC_FSM_CONTINUE;
2500   }
2501
2502   /* Send REKEY packet to start rekey protocol */
2503   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2504     /** Error sending packet */
2505     SILC_LOG_DEBUG(("Error sending packet"));
2506     ske->status = SILC_SKE_STATUS_ERROR;
2507     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2508     return SILC_FSM_CONTINUE;
2509   }
2510
2511   /* If doing rekey without PFS, move directly to the end of the protocol. */
2512   if (!ske->rekey->pfs) {
2513     /** Rekey without PFS */
2514     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2515     return SILC_FSM_CONTINUE;
2516   }
2517
2518   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2519                                         &ske->prop->group);
2520   if (status != SILC_SKE_STATUS_OK) {
2521     /** Unknown group */
2522     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2523     return SILC_FSM_CONTINUE;
2524   }
2525
2526   /** Rekey with PFS */
2527   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2528   return SILC_FSM_CONTINUE;
2529 }
2530
2531 /* Sends REKEY_DONE packet to finish the protocol. */
2532
2533 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2534 {
2535   SilcSKE ske = fsm_context;
2536   SilcCipher send_key;
2537   SilcHmac hmac_send;
2538   SilcHash hash;
2539   SilcUInt32 key_len, block_len, hash_len, x_len;
2540   unsigned char *pfsbuf;
2541
2542   SILC_LOG_DEBUG(("Start"));
2543
2544   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2545   key_len = silc_cipher_get_key_len(send_key);
2546   block_len = silc_cipher_get_block_len(send_key);
2547   hash = ske->prop->hash;
2548   hash_len = silc_hash_len(hash);
2549
2550   /* Process key material */
2551   if (ske->rekey->pfs) {
2552     /* PFS */
2553     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2554     if (pfsbuf) {
2555       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2556                                                        block_len, key_len,
2557                                                        hash_len, hash);
2558       memset(pfsbuf, 0, x_len);
2559       silc_free(pfsbuf);
2560     }
2561   } else {
2562     /* No PFS */
2563     ske->keymat =
2564       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2565                                          ske->rekey->enc_key_len / 8,
2566                                          block_len, key_len,
2567                                          hash_len, hash);
2568   }
2569
2570   if (!ske->keymat) {
2571     SILC_LOG_ERROR(("Error processing key material"));
2572     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2573     return SILC_FSM_CONTINUE;
2574   }
2575
2576   ske->prop->cipher = send_key;
2577   ske->prop->hmac = hmac_send;
2578
2579   /* Get sending keys */
2580   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2581                          &hmac_send, NULL, NULL)) {
2582     /** Cannot get keys */
2583     ske->status = SILC_SKE_STATUS_ERROR;
2584     ske->prop->cipher = NULL;
2585     ske->prop->hmac = NULL;
2586     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2587     return SILC_FSM_CONTINUE;
2588   }
2589
2590   ske->prop->cipher = NULL;
2591   ske->prop->hmac = NULL;
2592
2593   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2594      packet sent after this call will be protected with the new keys. */
2595   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2596                             TRUE)) {
2597     /** Cannot set keys */
2598     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2599     ske->status = SILC_SKE_STATUS_ERROR;
2600     silc_cipher_free(send_key);
2601     silc_hmac_free(hmac_send);
2602     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2603     return SILC_FSM_CONTINUE;
2604   }
2605
2606   /** Wait for REKEY_DONE */
2607   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2608   return SILC_FSM_WAIT;
2609 }
2610
2611 /* Rekey protocol end */
2612
2613 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2614 {
2615   SilcSKE ske = fsm_context;
2616   SilcCipher receive_key;
2617   SilcHmac hmac_receive;
2618   SilcSKERekeyMaterial rekey;
2619
2620   SILC_LOG_DEBUG(("Start"));
2621
2622   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2623     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2624     silc_packet_free(ske->packet);
2625     ske->packet = NULL;
2626     return SILC_FSM_WAIT;
2627   }
2628
2629   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2630   ske->prop->cipher = receive_key;
2631   ske->prop->hmac = hmac_receive;
2632
2633   /* Get receiving keys */
2634   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2635                          NULL, &hmac_receive, NULL)) {
2636     /** Cannot get keys */
2637     ske->status = SILC_SKE_STATUS_ERROR;
2638     ske->prop->cipher = NULL;
2639     ske->prop->hmac = NULL;
2640     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2641     return SILC_FSM_CONTINUE;
2642   }
2643
2644   /* Set new receiving keys into use.  All packets received after this will
2645      be decrypted with the new keys. */
2646   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2647                             hmac_receive, FALSE)) {
2648     /** Cannot set keys */
2649     SILC_LOG_DEBUG(("Cannot set new keys"));
2650     ske->status = SILC_SKE_STATUS_ERROR;
2651     silc_cipher_free(receive_key);
2652     silc_hmac_free(hmac_receive);
2653     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2654     return SILC_FSM_CONTINUE;
2655   }
2656
2657   SILC_LOG_DEBUG(("Rekey completed successfully"));
2658
2659   /* Generate new rekey material */
2660   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2661   if (!rekey) {
2662     /** No memory */
2663     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2664     ske->prop->cipher = NULL;
2665     ske->prop->hmac = NULL;
2666     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2667     return SILC_FSM_CONTINUE;
2668   }
2669   rekey->pfs = ske->rekey->pfs;
2670   ske->rekey = rekey;
2671
2672   ske->prop->cipher = NULL;
2673   ske->prop->hmac = NULL;
2674   silc_packet_free(ske->packet);
2675   ske->packet = NULL;
2676   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2677   silc_schedule_task_del_by_context(ske->schedule, ske);
2678
2679   /* Call completion */
2680   silc_ske_completion(ske);
2681
2682   return SILC_FSM_FINISH;
2683 }
2684
2685 /* Starts rekey protocol as initiator */
2686
2687 SilcAsyncOperation
2688 silc_ske_rekey_initiator(SilcSKE ske,
2689                          SilcPacketStream stream,
2690                          SilcSKERekeyMaterial rekey)
2691 {
2692   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2693
2694   if (!ske || !stream || !rekey) {
2695     SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2696     SILC_ASSERT(rekey);
2697     return NULL;
2698   }
2699
2700   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2701     return NULL;
2702
2703   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2704     return NULL;
2705
2706   ske->rekey = rekey;
2707   ske->responder = FALSE;
2708   ske->rekeying = TRUE;
2709   ++ ske->refcnt;
2710
2711   /* Link to packet stream to get key exchange packets */
2712   ske->stream = stream;
2713   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2714                           SILC_PACKET_REKEY,
2715                           SILC_PACKET_REKEY_DONE,
2716                           SILC_PACKET_KEY_EXCHANGE_2,
2717                           SILC_PACKET_SUCCESS,
2718                           SILC_PACKET_FAILURE, -1);
2719
2720   /* Start SKE rekey as initiator */
2721   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2722
2723   return &ske->op;
2724 }
2725
2726 /***************************** Responder Rekey ******************************/
2727
2728 /* Wait for initiator's packet */
2729
2730 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2731 {
2732   SilcSKE ske = fsm_context;
2733
2734   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2735
2736   if (ske->aborted) {
2737     /** Aborted */
2738     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2739     return SILC_FSM_CONTINUE;
2740   }
2741
2742   /* Add rekey exchange timeout */
2743   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2744                                  ske, 30, 0);
2745
2746   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2747
2748   /* If REKEY packet already received process it directly */
2749   if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2750     return SILC_FSM_CONTINUE;
2751
2752   /* Wait for REKEY */
2753   return SILC_FSM_WAIT;
2754 }
2755
2756 /* Process initiator's REKEY packet */
2757
2758 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2759 {
2760   SilcSKE ske = fsm_context;
2761   SilcSKEStatus status;
2762
2763   SILC_LOG_DEBUG(("Start"));
2764
2765   if (ske->packet->type != SILC_PACKET_REKEY) {
2766     ske->status = SILC_SKE_STATUS_ERROR;
2767     silc_packet_free(ske->packet);
2768     ske->packet = NULL;
2769     silc_fsm_next(fsm, silc_ske_st_responder_error);
2770     return SILC_FSM_CONTINUE;
2771   }
2772
2773   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2774   if (!ske->prop) {
2775     /** No memory */
2776     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2777     silc_fsm_next(fsm, silc_ske_st_responder_error);
2778     return SILC_FSM_CONTINUE;
2779   }
2780
2781   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2782     /** Cannot allocate hash */
2783     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2784     silc_fsm_next(fsm, silc_ske_st_responder_error);
2785     return SILC_FSM_CONTINUE;
2786   }
2787
2788   /* If doing rekey without PFS, move directly to the end of the protocol. */
2789   if (!ske->rekey->pfs) {
2790     /** Rekey without PFS */
2791     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2792     return SILC_FSM_CONTINUE;
2793   }
2794
2795   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2796                                         &ske->prop->group);
2797   if (status != SILC_SKE_STATUS_OK) {
2798     /** Unknown group */
2799     silc_fsm_next(fsm, silc_ske_st_responder_error);
2800     return SILC_FSM_CONTINUE;
2801   }
2802
2803   /** Rekey with PFS */
2804   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2805   return SILC_FSM_WAIT;
2806 }
2807
2808 /* Sends REKEY_DONE packet to finish the protocol. */
2809
2810 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2811 {
2812   SilcSKE ske = fsm_context;
2813   SilcCipher send_key;
2814   SilcHmac hmac_send;
2815   SilcHash hash;
2816   SilcUInt32 key_len, block_len, hash_len, x_len;
2817   unsigned char *pfsbuf;
2818
2819   SILC_LOG_DEBUG(("Start"));
2820
2821   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2822   key_len = silc_cipher_get_key_len(send_key);
2823   block_len = silc_cipher_get_block_len(send_key);
2824   hash = ske->prop->hash;
2825   hash_len = silc_hash_len(hash);
2826
2827   /* Process key material */
2828   if (ske->rekey->pfs) {
2829     /* PFS */
2830     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2831     if (pfsbuf) {
2832       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2833                                                        block_len, key_len,
2834                                                        hash_len, hash);
2835       memset(pfsbuf, 0, x_len);
2836       silc_free(pfsbuf);
2837     }
2838   } else {
2839     /* No PFS */
2840     ske->keymat =
2841       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2842                                          ske->rekey->enc_key_len / 8,
2843                                          block_len, key_len,
2844                                          hash_len, hash);
2845   }
2846
2847   if (!ske->keymat) {
2848     SILC_LOG_ERROR(("Error processing key material"));
2849     silc_fsm_next(fsm, silc_ske_st_responder_error);
2850     return SILC_FSM_CONTINUE;
2851   }
2852
2853   ske->prop->cipher = send_key;
2854   ske->prop->hmac = hmac_send;
2855
2856   /* Get sending keys */
2857   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2858                          &hmac_send, NULL, NULL)) {
2859     /** Cannot get keys */
2860     ske->status = SILC_SKE_STATUS_ERROR;
2861     ske->prop->cipher = NULL;
2862     ske->prop->hmac = NULL;
2863     silc_fsm_next(fsm, silc_ske_st_responder_error);
2864     return SILC_FSM_CONTINUE;
2865   }
2866
2867   ske->prop->cipher = NULL;
2868   ske->prop->hmac = NULL;
2869
2870   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2871      packet sent after this call will be protected with the new keys. */
2872   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2873                             TRUE)) {
2874     /** Cannot set keys */
2875     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2876     ske->status = SILC_SKE_STATUS_ERROR;
2877     silc_cipher_free(send_key);
2878     silc_hmac_free(hmac_send);
2879     silc_fsm_next(fsm, silc_ske_st_responder_error);
2880     return SILC_FSM_CONTINUE;
2881   }
2882
2883   /** Wait for REKEY_DONE */
2884   silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2885   return SILC_FSM_WAIT;
2886 }
2887
2888 /* Rekey protocol end */
2889
2890 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2891 {
2892   SilcSKE ske = fsm_context;
2893   SilcCipher receive_key;
2894   SilcHmac hmac_receive;
2895   SilcSKERekeyMaterial rekey;
2896
2897   SILC_LOG_DEBUG(("Start"));
2898
2899   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2900     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2901     silc_packet_free(ske->packet);
2902     ske->packet = NULL;
2903     return SILC_FSM_WAIT;
2904   }
2905
2906   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2907   ske->prop->cipher = receive_key;
2908   ske->prop->hmac = hmac_receive;
2909
2910   /* Get receiving keys */
2911   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2912                          NULL, &hmac_receive, NULL)) {
2913     /** Cannot get keys */
2914     ske->status = SILC_SKE_STATUS_ERROR;
2915     ske->prop->cipher = NULL;
2916     ske->prop->hmac = NULL;
2917     silc_fsm_next(fsm, silc_ske_st_responder_error);
2918     return SILC_FSM_CONTINUE;
2919   }
2920
2921   /* Set new receiving keys into use.  All packets received after this will
2922      be decrypted with the new keys. */
2923   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2924                             hmac_receive, FALSE)) {
2925     /** Cannot set keys */
2926     SILC_LOG_DEBUG(("Cannot set new keys"));
2927     ske->status = SILC_SKE_STATUS_ERROR;
2928     ske->prop->cipher = NULL;
2929     ske->prop->hmac = NULL;
2930     silc_cipher_free(receive_key);
2931     silc_hmac_free(hmac_receive);
2932     silc_fsm_next(fsm, silc_ske_st_responder_error);
2933     return SILC_FSM_CONTINUE;
2934   }
2935
2936   SILC_LOG_DEBUG(("Rekey completed successfully"));
2937
2938   /* Generate new rekey material */
2939   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2940   if (!rekey) {
2941     /** No memory */
2942     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2943     ske->prop->cipher = NULL;
2944     ske->prop->hmac = NULL;
2945     silc_fsm_next(fsm, silc_ske_st_responder_error);
2946     return SILC_FSM_CONTINUE;
2947   }
2948   rekey->pfs = ske->rekey->pfs;
2949   ske->rekey = rekey;
2950
2951   ske->prop->cipher = NULL;
2952   ske->prop->hmac = NULL;
2953   silc_packet_free(ske->packet);
2954   ske->packet = NULL;
2955   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2956   silc_schedule_task_del_by_context(ske->schedule, ske);
2957
2958   /* Call completion */
2959   silc_ske_completion(ske);
2960
2961   return SILC_FSM_FINISH;
2962 }
2963
2964 /* Starts rekey protocol as responder */
2965
2966 SilcAsyncOperation
2967 silc_ske_rekey_responder(SilcSKE ske,
2968                          SilcPacketStream stream,
2969                          SilcSKERekeyMaterial rekey,
2970                          SilcPacket packet)
2971 {
2972   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2973
2974   if (!ske || !stream || !rekey)
2975     return NULL;
2976
2977   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2978     return NULL;
2979
2980   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2981     return NULL;
2982
2983   ske->rekey = rekey;
2984   ske->responder = TRUE;
2985   ske->rekeying = TRUE;
2986   ske->packet = packet;
2987   ++ ske->refcnt;
2988
2989   /* Link to packet stream to get key exchange packets */
2990   ske->stream = stream;
2991   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2992                           SILC_PACKET_REKEY,
2993                           SILC_PACKET_REKEY_DONE,
2994                           SILC_PACKET_KEY_EXCHANGE_1,
2995                           SILC_PACKET_SUCCESS,
2996                           SILC_PACKET_FAILURE, -1);
2997
2998   /* Start SKE rekey as responder */
2999   silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3000
3001   return &ske->op;
3002 }
3003
3004 /* Processes the provided key material `data' as the SILC protocol
3005    specification defines. */
3006
3007 SilcSKEKeyMaterial
3008 silc_ske_process_key_material_data(unsigned char *data,
3009                                    SilcUInt32 data_len,
3010                                    SilcUInt32 req_iv_len,
3011                                    SilcUInt32 req_enc_key_len,
3012                                    SilcUInt32 req_hmac_key_len,
3013                                    SilcHash hash)
3014 {
3015   SilcBuffer buf;
3016   unsigned char hashd[SILC_HASH_MAXLEN];
3017   SilcUInt32 hash_len = req_hmac_key_len;
3018   SilcUInt32 enc_key_len = req_enc_key_len / 8;
3019   SilcSKEKeyMaterial key;
3020
3021   SILC_LOG_DEBUG(("Start"));
3022
3023   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3024     return NULL;
3025
3026   key = silc_calloc(1, sizeof(*key));
3027   if (!key)
3028     return NULL;
3029
3030   buf = silc_buffer_alloc_size(1 + data_len);
3031   if (!buf)
3032     return NULL;
3033   silc_buffer_format(buf,
3034                      SILC_STR_UI_CHAR(0),
3035                      SILC_STR_DATA(data, data_len),
3036                      SILC_STR_END);
3037
3038   /* Take IVs */
3039   memset(hashd, 0, sizeof(hashd));
3040   buf->data[0] = 0;
3041   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3042   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3043   memcpy(key->send_iv, hashd, req_iv_len);
3044   memset(hashd, 0, sizeof(hashd));
3045   buf->data[0] = 1;
3046   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3047   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3048   memcpy(key->receive_iv, hashd, req_iv_len);
3049   key->iv_len = req_iv_len;
3050
3051   /* Take the encryption keys. If requested key size is more than
3052      the size of hash length we will distribute more key material
3053      as protocol defines. */
3054   buf->data[0] = 2;
3055   if (enc_key_len > hash_len) {
3056     SilcBuffer dist;
3057     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3058         k3[SILC_HASH_MAXLEN];
3059     unsigned char *dtmp;
3060
3061     /* XXX */
3062     if (enc_key_len > (3 * hash_len))
3063       return NULL;
3064
3065     /* Take first round */
3066     memset(k1, 0, sizeof(k1));
3067     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3068
3069     /* Take second round */
3070     dist = silc_buffer_alloc_size(data_len + hash_len);
3071     if (!dist)
3072       return NULL;
3073     silc_buffer_format(dist,
3074                        SILC_STR_DATA(data, data_len),
3075                        SILC_STR_DATA(k1, hash_len),
3076                        SILC_STR_END);
3077     memset(k2, 0, sizeof(k2));
3078     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3079
3080     /* Take third round */
3081     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3082     silc_buffer_pull_tail(dist, hash_len);
3083     silc_buffer_pull(dist, data_len + hash_len);
3084     silc_buffer_format(dist,
3085                        SILC_STR_DATA(k2, hash_len),
3086                        SILC_STR_END);
3087     silc_buffer_push(dist, data_len + hash_len);
3088     memset(k3, 0, sizeof(k3));
3089     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3090
3091     /* Then, save the keys */
3092     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3093     memcpy(dtmp, k1, hash_len);
3094     memcpy(dtmp + hash_len, k2, hash_len);
3095     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3096
3097     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3098     memcpy(key->send_enc_key, dtmp, enc_key_len);
3099     key->enc_key_len = req_enc_key_len;
3100
3101     memset(dtmp, 0, (3 * hash_len));
3102     memset(k1, 0, sizeof(k1));
3103     memset(k2, 0, sizeof(k2));
3104     memset(k3, 0, sizeof(k3));
3105     silc_free(dtmp);
3106     silc_buffer_clear(dist);
3107     silc_buffer_free(dist);
3108   } else {
3109     /* Take normal hash as key */
3110     memset(hashd, 0, sizeof(hashd));
3111     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3112     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3113     memcpy(key->send_enc_key, hashd, enc_key_len);
3114     key->enc_key_len = req_enc_key_len;
3115   }
3116
3117   buf->data[0] = 3;
3118   if (enc_key_len > hash_len) {
3119     SilcBuffer dist;
3120     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3121         k3[SILC_HASH_MAXLEN];
3122     unsigned char *dtmp;
3123
3124     /* XXX */
3125     if (enc_key_len > (3 * hash_len))
3126       return NULL;
3127
3128     /* Take first round */
3129     memset(k1, 0, sizeof(k1));
3130     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3131
3132     /* Take second round */
3133     dist = silc_buffer_alloc_size(data_len + hash_len);
3134     if (!dist)
3135       return NULL;
3136     silc_buffer_format(dist,
3137                        SILC_STR_DATA(data, data_len),
3138                        SILC_STR_DATA(k1, hash_len),
3139                        SILC_STR_END);
3140     memset(k2, 0, sizeof(k2));
3141     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3142
3143     /* Take third round */
3144     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3145     silc_buffer_pull_tail(dist, hash_len);
3146     silc_buffer_pull(dist, data_len + hash_len);
3147     silc_buffer_format(dist,
3148                        SILC_STR_DATA(k2, hash_len),
3149                        SILC_STR_END);
3150     silc_buffer_push(dist, data_len + hash_len);
3151     memset(k3, 0, sizeof(k3));
3152     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3153
3154     /* Then, save the keys */
3155     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3156     memcpy(dtmp, k1, hash_len);
3157     memcpy(dtmp + hash_len, k2, hash_len);
3158     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3159
3160     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3161     memcpy(key->receive_enc_key, dtmp, enc_key_len);
3162     key->enc_key_len = req_enc_key_len;
3163
3164     memset(dtmp, 0, (3 * hash_len));
3165     memset(k1, 0, sizeof(k1));
3166     memset(k2, 0, sizeof(k2));
3167     memset(k3, 0, sizeof(k3));
3168     silc_free(dtmp);
3169     silc_buffer_clear(dist);
3170     silc_buffer_free(dist);
3171   } else {
3172     /* Take normal hash as key */
3173     memset(hashd, 0, sizeof(hashd));
3174     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3175     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3176     memcpy(key->receive_enc_key, hashd, enc_key_len);
3177     key->enc_key_len = req_enc_key_len;
3178   }
3179
3180   /* Take HMAC keys */
3181   memset(hashd, 0, sizeof(hashd));
3182   buf->data[0] = 4;
3183   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3184   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3185   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3186   memset(hashd, 0, sizeof(hashd));
3187   buf->data[0] = 5;
3188   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3189   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3190   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3191   key->hmac_key_len = req_hmac_key_len;
3192   memset(hashd, 0, sizeof(hashd));
3193
3194   silc_buffer_clear(buf);
3195   silc_buffer_free(buf);
3196
3197   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3198
3199   return key;
3200 }
3201
3202 /* Processes negotiated key material as protocol specifies. This returns
3203    the actual keys to be used in the SILC. */
3204
3205 SilcSKEKeyMaterial
3206 silc_ske_process_key_material(SilcSKE ske,
3207                               SilcUInt32 req_iv_len,
3208                               SilcUInt32 req_enc_key_len,
3209                               SilcUInt32 req_hmac_key_len,
3210                               SilcSKERekeyMaterial *rekey)
3211 {
3212   SilcBuffer buf;
3213   unsigned char *tmpbuf;
3214   SilcUInt32 klen;
3215   SilcSKEKeyMaterial key;
3216
3217   /* Encode KEY to binary data */
3218   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3219
3220   buf = silc_buffer_alloc_size(klen + ske->hash_len);
3221   if (!buf)
3222     return NULL;
3223   silc_buffer_format(buf,
3224                      SILC_STR_DATA(tmpbuf, klen),
3225                      SILC_STR_DATA(ske->hash, ske->hash_len),
3226                      SILC_STR_END);
3227
3228   /* Process the key material */
3229   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3230                                            req_iv_len, req_enc_key_len,
3231                                            req_hmac_key_len,
3232                                            ske->prop->hash);
3233
3234   memset(tmpbuf, 0, klen);
3235   silc_free(tmpbuf);
3236   silc_buffer_clear(buf);
3237   silc_buffer_free(buf);
3238
3239   if (rekey) {
3240     *rekey = silc_ske_make_rekey_material(ske, key);
3241     if (!(*rekey))
3242       return NULL;
3243   }
3244
3245   return key;
3246 }
3247
3248 /* Free key material structure */
3249
3250 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3251 {
3252   if (!key)
3253     return;
3254
3255   if (key->send_iv)
3256     silc_free(key->send_iv);
3257   if (key->receive_iv)
3258     silc_free(key->receive_iv);
3259   if (key->send_enc_key) {
3260     memset(key->send_enc_key, 0, key->enc_key_len / 8);
3261     silc_free(key->send_enc_key);
3262   }
3263   if (key->receive_enc_key) {
3264     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3265     silc_free(key->receive_enc_key);
3266   }
3267   if (key->send_hmac_key) {
3268     memset(key->send_hmac_key, 0, key->hmac_key_len);
3269     silc_free(key->send_hmac_key);
3270   }
3271   if (key->receive_hmac_key) {
3272     memset(key->receive_hmac_key, 0, key->hmac_key_len);
3273     silc_free(key->receive_hmac_key);
3274   }
3275   silc_free(key);
3276 }
3277
3278 /* Free rekey material */
3279
3280 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3281 {
3282   if (!rekey)
3283     return;
3284   if (rekey->send_enc_key) {
3285     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3286     silc_free(rekey->send_enc_key);
3287   }
3288   silc_free(rekey->hash);
3289   silc_free(rekey);
3290 }
3291
3292 /* Set keys into use */
3293
3294 SilcBool silc_ske_set_keys(SilcSKE ske,
3295                            SilcSKEKeyMaterial keymat,
3296                            SilcSKESecurityProperties prop,
3297                            SilcCipher *ret_send_key,
3298                            SilcCipher *ret_receive_key,
3299                            SilcHmac *ret_hmac_send,
3300                            SilcHmac *ret_hmac_receive,
3301                            SilcHash *ret_hash)
3302 {
3303   unsigned char iv[SILC_HASH_MAXLEN];
3304   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3305
3306   /* Allocate ciphers to be used in the communication */
3307   if (ret_send_key) {
3308     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3309                            ret_send_key))
3310       return FALSE;
3311   }
3312   if (ret_receive_key) {
3313     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3314                            ret_receive_key))
3315       return FALSE;
3316   }
3317
3318   /* Allocate HMACs */
3319   if (ret_hmac_send) {
3320     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3321                          ret_hmac_send))
3322       return FALSE;
3323   }
3324   if (ret_hmac_receive) {
3325     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3326                          ret_hmac_receive))
3327       return FALSE;
3328   }
3329
3330   /* Allocate hash */
3331   if (ret_hash) {
3332     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3333       return FALSE;
3334   }
3335
3336   /* Set key material */
3337   memset(iv, 0, sizeof(iv));
3338   if (ske->responder) {
3339     if (ret_send_key) {
3340       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3341                           keymat->enc_key_len, TRUE);
3342
3343       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3344         /* Counter mode */
3345         if (!ske->rekeying) {
3346           /* Set IV. */
3347           memcpy(iv, ske->hash, 4);
3348           if (!iv_included)
3349             memcpy(iv + 4, keymat->receive_iv, 8);
3350         } else {
3351           /* Rekey, recompute the truncated hash value. */
3352           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3353           if (!iv_included)
3354             memcpy(iv + 4, keymat->receive_iv, 8);
3355           else
3356             memset(iv + 4, 0, 12);
3357         }
3358
3359         silc_cipher_set_iv(*ret_send_key, iv);
3360       } else {
3361         /* Other modes */
3362         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3363       }
3364     }
3365     if (ret_receive_key) {
3366       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3367                           keymat->enc_key_len, FALSE);
3368
3369       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3370         /* Counter mode */
3371         if (!ske->rekeying) {
3372           /* Set IV. */
3373           memcpy(iv, ske->hash, 4);
3374           if (!iv_included)
3375             memcpy(iv + 4, keymat->send_iv, 8);
3376         } else {
3377           /* Rekey, recompute the truncated hash value. */
3378           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3379           if (!iv_included)
3380             memcpy(iv + 4, keymat->send_iv, 8);
3381           else
3382             memset(iv + 4, 0, 12);
3383         }
3384
3385         silc_cipher_set_iv(*ret_receive_key, iv);
3386       } else {
3387         /* Other modes */
3388         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3389       }
3390     }
3391     if (ret_hmac_send)
3392       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3393                         keymat->hmac_key_len);
3394     if (ret_hmac_receive)
3395       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3396                         keymat->hmac_key_len);
3397   } else {
3398     if (ret_send_key) {
3399       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3400                           keymat->enc_key_len, TRUE);
3401
3402       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3403         /* Counter mode */
3404         if (!ske->rekeying) {
3405           /* Set IV. */
3406           memcpy(iv, ske->hash, 4);
3407           if (!iv_included)
3408             memcpy(iv + 4, keymat->send_iv, 8);
3409         } else {
3410           /* Rekey, recompute the truncated hash value. */
3411           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3412           if (!iv_included)
3413             memcpy(iv + 4, keymat->send_iv, 8);
3414           else
3415             memset(iv + 4, 0, 12);
3416         }
3417
3418         silc_cipher_set_iv(*ret_send_key, iv);
3419       } else {
3420         /* Other modes */
3421         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3422       }
3423     }
3424     if (ret_receive_key) {
3425       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3426                           keymat->enc_key_len, FALSE);
3427
3428       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3429         /* Counter mode */
3430         if (!ske->rekeying) {
3431           /* Set IV.  If IV Included flag was negotiated we only set the
3432              truncated hash value. */
3433           memcpy(iv, ske->hash, 4);
3434           if (!iv_included)
3435             memcpy(iv + 4, keymat->receive_iv, 8);
3436         } else {
3437           /* Rekey, recompute the truncated hash value. */
3438           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3439           if (!iv_included)
3440             memcpy(iv + 4, keymat->receive_iv, 8);
3441           else
3442             memset(iv + 4, 0, 12);
3443         }
3444
3445         silc_cipher_set_iv(*ret_receive_key, iv);
3446       } else {
3447         /* Other modes */
3448         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3449       }
3450     }
3451     if (ret_hmac_send)
3452       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3453                         keymat->hmac_key_len);
3454     if (ret_hmac_receive)
3455       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3456                         keymat->hmac_key_len);
3457   }
3458
3459   return TRUE;
3460 }
3461
3462 const char *silc_ske_status_string[] =
3463 {
3464   /* Official */
3465   "Ok",
3466   "Unexpected error occurred",
3467   "Bad payload in packet",
3468   "Unsupported group",
3469   "Unsupported cipher",
3470   "Unsupported PKCS",
3471   "Unsupported hash function",
3472   "Unsupported HMAC",
3473   "Unsupported public key (or certificate)",
3474   "Incorrect signature",
3475   "Bad or unsupported version",
3476   "Invalid cookie",
3477
3478   /* Other errors */
3479   "Remote did not provide public key",
3480   "Bad reserved field in packet",
3481   "Bad payload length in packet",
3482   "Error computing signature",
3483   "System out of memory",
3484   "Key exchange timeout",
3485
3486   NULL
3487 };
3488
3489 /* Maps status to readable string and returns the string. If string is not
3490    found and empty character string ("") is returned. */
3491
3492 const char *silc_ske_map_status(SilcSKEStatus status)
3493 {
3494   int i;
3495
3496   for (i = 0; silc_ske_status_string[i]; i++)
3497     if (status == i)
3498       return silc_ske_status_string[i];
3499
3500   return "";
3501 }
3502
3503 /* Parses remote host's version string. */
3504
3505 SilcBool silc_ske_parse_version(SilcSKE ske,
3506                                 SilcUInt32 *protocol_version,
3507                                 char **protocol_version_string,
3508                                 SilcUInt32 *software_version,
3509                                 char **software_version_string,
3510                                 char **vendor_version)
3511 {
3512   return silc_parse_version_string(ske->remote_version,
3513                                    protocol_version,
3514                                    protocol_version_string,
3515                                    software_version,
3516                                    software_version_string,
3517                                    vendor_version);
3518 }
3519
3520 /* Get security properties */
3521
3522 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3523 {
3524   return ske->prop;
3525 }
3526
3527 /* Get key material */
3528
3529 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3530 {
3531   return ske->keymat;
3532 }