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