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