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