Call completion synchronously instead of through FSM destructor.
[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
1039   return ske;
1040 }
1041
1042 /* Free's SKE object. */
1043
1044 void silc_ske_free(SilcSKE ske)
1045 {
1046   SILC_LOG_DEBUG(("Freeing Key Exchange object"));
1047
1048   if (!ske)
1049     return;
1050
1051   if (ske->running) {
1052     ske->freed = TRUE;
1053
1054     if (ske->aborted) {
1055       /* If already aborted, destroy the session immediately */
1056       ske->packet = NULL;
1057       ske->status = SILC_SKE_STATUS_ERROR;
1058       if (ske->responder)
1059         silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1060       else
1061         silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1062       silc_fsm_continue_sync(&ske->fsm);
1063     }
1064     return;
1065   }
1066
1067   /* Free start payload */
1068   if (ske->start_payload)
1069     silc_ske_payload_start_free(ske->start_payload);
1070
1071   /* Free KE payload */
1072   if (ske->ke1_payload)
1073     silc_ske_payload_ke_free(ske->ke1_payload);
1074   if (ske->ke2_payload)
1075     silc_ske_payload_ke_free(ske->ke2_payload);
1076   silc_free(ske->remote_version);
1077
1078   /* Free rest */
1079   if (ske->prop) {
1080     if (ske->prop->group)
1081       silc_ske_group_free(ske->prop->group);
1082     if (ske->prop->cipher)
1083       silc_cipher_free(ske->prop->cipher);
1084     if (ske->prop->hash)
1085       silc_hash_free(ske->prop->hash);
1086     if (ske->prop->hmac)
1087       silc_hmac_free(ske->prop->hmac);
1088     silc_free(ske->prop);
1089   }
1090   if (ske->keymat)
1091     silc_ske_free_key_material(ske->keymat);
1092   if (ske->start_payload_copy)
1093     silc_buffer_free(ske->start_payload_copy);
1094   if (ske->x) {
1095     silc_mp_uninit(ske->x);
1096     silc_free(ske->x);
1097   }
1098   if (ske->KEY) {
1099     silc_mp_uninit(ske->KEY);
1100     silc_free(ske->KEY);
1101   }
1102   silc_free(ske->retrans.data);
1103   silc_free(ske->hash);
1104   silc_free(ske->callbacks);
1105
1106   memset(ske, 'F', sizeof(*ske));
1107   silc_free(ske);
1108 }
1109
1110 /* Return user context */
1111
1112 void *silc_ske_get_context(SilcSKE ske)
1113 {
1114   return ske->user_data;
1115 }
1116
1117 /* Sets protocol callbacks */
1118
1119 void silc_ske_set_callbacks(SilcSKE ske,
1120                             SilcSKEVerifyCb verify_key,
1121                             SilcSKECompletionCb completed,
1122                             void *context)
1123 {
1124   if (ske->callbacks)
1125     silc_free(ske->callbacks);
1126   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1127   if (!ske->callbacks)
1128     return;
1129   ske->callbacks->verify_key = verify_key;
1130   ske->callbacks->completed = completed;
1131   ske->callbacks->context = context;
1132 }
1133
1134
1135 /******************************** Initiator *********************************/
1136
1137 /* Start protocol.  Send our proposal */
1138
1139 SILC_FSM_STATE(silc_ske_st_initiator_start)
1140 {
1141   SilcSKE ske = fsm_context;
1142   SilcBuffer payload_buf;
1143   SilcStatus status;
1144
1145   SILC_LOG_DEBUG(("Start"));
1146
1147   if (ske->aborted) {
1148     /** Aborted */
1149     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1150     return SILC_FSM_CONTINUE;
1151   }
1152
1153   /* Encode the payload */
1154   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1155                                          &payload_buf);
1156   if (status != SILC_SKE_STATUS_OK) {
1157     /** Error encoding Start Payload */
1158     ske->status = status;
1159     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1160     return SILC_FSM_CONTINUE;
1161   }
1162
1163   /* Save the the payload buffer for future use. It is later used to
1164      compute the HASH value. */
1165   ske->start_payload_copy = payload_buf;
1166
1167   /* Send the packet. */
1168   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1169                             silc_buffer_data(payload_buf),
1170                             silc_buffer_len(payload_buf))) {
1171     /** Error sending packet */
1172     SILC_LOG_DEBUG(("Error sending packet"));
1173     ske->status = SILC_SKE_STATUS_ERROR;
1174     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1175     return SILC_FSM_CONTINUE;
1176   }
1177
1178   /* Add key exchange timeout */
1179   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1180                                  ske, ske->timeout, 0);
1181
1182   /** Wait for responder proposal */
1183   SILC_LOG_DEBUG(("Waiting for responder proposal"));
1184   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1185   return SILC_FSM_WAIT;
1186 }
1187
1188 /* Phase-1.  Receives responder's proposal */
1189
1190 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1191 {
1192   SilcSKE ske = fsm_context;
1193   SilcSKEStatus status;
1194   SilcSKEStartPayload payload;
1195   SilcSKESecurityProperties prop;
1196   SilcSKEDiffieHellmanGroup group = NULL;
1197   SilcBuffer packet_buf = &ske->packet->buffer;
1198   SilcUInt16 remote_port = 0;
1199   SilcID id;
1200   int coff = 0;
1201
1202   SILC_LOG_DEBUG(("Start"));
1203
1204   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1205     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1206     silc_ske_install_retransmission(ske);
1207     silc_packet_free(ske->packet);
1208     ske->packet = NULL;
1209     return SILC_FSM_WAIT;
1210   }
1211
1212   /* Decode the payload */
1213   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1214   if (status != SILC_SKE_STATUS_OK) {
1215     /** Error decoding Start Payload */
1216     silc_packet_free(ske->packet);
1217     ske->packet = NULL;
1218     ske->status = status;
1219     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1220     return SILC_FSM_CONTINUE;
1221   }
1222
1223   /* Get remote ID and set it to stream */
1224   if (ske->packet->src_id_len) {
1225     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1226                    ske->packet->src_id_type,
1227                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1228                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1229                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1230                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1231     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1232                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1233                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1234   }
1235
1236   silc_packet_free(ske->packet);
1237   ske->packet = NULL;
1238
1239   /* Check that the cookie is returned unmodified.  In case IV included
1240      flag and session port has been set, the first two bytes of cookie
1241      are the session port and we ignore them in this check. */
1242   if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1243     /* Take remote port */
1244     SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1245     coff = 2;
1246   }
1247   if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1248              SILC_SKE_COOKIE_LEN - coff)) {
1249     /** Invalid cookie */
1250     SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1251     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1252     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1253     return SILC_FSM_CONTINUE;
1254   }
1255
1256   /* Check version string */
1257   ske->remote_version = silc_memdup(payload->version, payload->version_len);
1258   status = silc_ske_check_version(ske);
1259   if (status != SILC_SKE_STATUS_OK) {
1260     /** Version mismatch */
1261     ske->status = status;
1262     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1263     return SILC_FSM_CONTINUE;
1264   }
1265
1266   /* Free our KE Start Payload context, we don't need it anymore. */
1267   silc_ske_payload_start_free(ske->start_payload);
1268   ske->start_payload = NULL;
1269
1270   /* Take the selected security properties into use while doing
1271      the key exchange.  This is used only while doing the key
1272      exchange. */
1273   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1274   if (!ske->prop)
1275     goto err;
1276   prop->flags = payload->flags;
1277   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1278   if (status != SILC_SKE_STATUS_OK)
1279     goto err;
1280
1281   prop->group = group;
1282   prop->remote_port = remote_port;
1283
1284   if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1285     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1286     goto err;
1287   }
1288   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1289     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1290     goto err;
1291   }
1292   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1293     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1294     goto err;
1295   }
1296   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1297     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1298     goto err;
1299   }
1300
1301   /* Save remote's KE Start Payload */
1302   ske->start_payload = payload;
1303
1304   /** Send KE Payload */
1305   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1306   return SILC_FSM_CONTINUE;
1307
1308  err:
1309   if (payload)
1310     silc_ske_payload_start_free(payload);
1311   if (group)
1312     silc_ske_group_free(group);
1313   if (prop->cipher)
1314     silc_cipher_free(prop->cipher);
1315   if (prop->hash)
1316     silc_hash_free(prop->hash);
1317   if (prop->hmac)
1318     silc_hmac_free(prop->hmac);
1319   silc_free(prop);
1320   ske->prop = NULL;
1321
1322   if (status == SILC_SKE_STATUS_OK)
1323     status = SILC_SKE_STATUS_ERROR;
1324
1325   /** Error */
1326   ske->status = status;
1327   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1328   return SILC_FSM_CONTINUE;
1329 }
1330
1331 /* Phase-2.  Send KE payload */
1332
1333 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1334 {
1335   SilcSKE ske = fsm_context;
1336   SilcSKEStatus status;
1337   SilcBuffer payload_buf;
1338   SilcMPInt *x;
1339   SilcSKEKEPayload payload;
1340   SilcUInt32 pk_len;
1341
1342   SILC_LOG_DEBUG(("Start"));
1343
1344   /* Create the random number x, 1 < x < q. */
1345   x = silc_calloc(1, sizeof(*x));
1346   if (!x){
1347     /** Out of memory */
1348     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1349     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1350     return SILC_FSM_CONTINUE;
1351   }
1352   silc_mp_init(x);
1353   status =
1354     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1355                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1356                         x);
1357   if (status != SILC_SKE_STATUS_OK) {
1358     /** Error generating random number */
1359     silc_mp_uninit(x);
1360     silc_free(x);
1361     ske->status = status;
1362     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1363     return SILC_FSM_CONTINUE;
1364   }
1365
1366   /* Encode the result to Key Exchange Payload. */
1367
1368   payload = silc_calloc(1, sizeof(*payload));
1369   if (!payload) {
1370     /** Out of memory */
1371     silc_mp_uninit(x);
1372     silc_free(x);
1373     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1374     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1375     return SILC_FSM_CONTINUE;
1376   }
1377   ske->ke1_payload = payload;
1378
1379   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1380
1381   /* Do the Diffie Hellman computation, e = g ^ x mod p */
1382   silc_mp_init(&payload->x);
1383   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1384                   &ske->prop->group->group);
1385
1386   /* Get public key */
1387   payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1388   if (!payload->pk_data) {
1389     /** Error encoding public key */
1390     silc_mp_uninit(x);
1391     silc_free(x);
1392     silc_mp_uninit(&payload->x);
1393     silc_free(payload);
1394     ske->ke1_payload = NULL;
1395     ske->status = SILC_SKE_STATUS_ERROR;
1396     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1397     return SILC_FSM_CONTINUE;
1398   }
1399   payload->pk_len = pk_len;
1400   payload->pk_type = silc_pkcs_get_type(ske->public_key);
1401
1402   /* Compute signature data if we are doing mutual authentication */
1403   if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1404     unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1405     SilcUInt32 hash_len, sign_len;
1406
1407     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1408     SILC_LOG_DEBUG(("Computing HASH_i value"));
1409
1410     /* Compute the hash value */
1411     memset(hash, 0, sizeof(hash));
1412     silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1413
1414     SILC_LOG_DEBUG(("Signing HASH_i value"));
1415
1416     /* Sign the hash value */
1417     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1418                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1419       /** Error computing signature */
1420       silc_mp_uninit(x);
1421       silc_free(x);
1422       silc_mp_uninit(&payload->x);
1423       silc_free(payload->pk_data);
1424       silc_free(payload);
1425       ske->ke1_payload = NULL;
1426       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1427       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1428       return SILC_FSM_CONTINUE;
1429     }
1430     payload->sign_data = silc_memdup(sign, sign_len);
1431     if (payload->sign_data)
1432       payload->sign_len = sign_len;
1433     memset(sign, 0, sizeof(sign));
1434   }
1435
1436   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1437   if (status != SILC_SKE_STATUS_OK) {
1438     /** Error encoding KE payload */
1439     silc_mp_uninit(x);
1440     silc_free(x);
1441     silc_mp_uninit(&payload->x);
1442     silc_free(payload->pk_data);
1443     silc_free(payload->sign_data);
1444     silc_free(payload);
1445     ske->ke1_payload = NULL;
1446     ske->status = status;
1447     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1448     return SILC_FSM_CONTINUE;
1449   }
1450
1451   ske->x = x;
1452
1453   /* Check for backwards compatibility */
1454
1455   /* Send the packet. */
1456   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1457                             silc_buffer_data(payload_buf),
1458                             silc_buffer_len(payload_buf))) {
1459     /** Error sending packet */
1460     SILC_LOG_DEBUG(("Error sending packet"));
1461     ske->status = SILC_SKE_STATUS_ERROR;
1462     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1463     return SILC_FSM_CONTINUE;
1464   }
1465
1466   silc_buffer_free(payload_buf);
1467
1468   /** Waiting responder's KE payload */
1469   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1470   return SILC_FSM_WAIT;
1471 }
1472
1473 /* Phase-3.  Process responder's KE payload */
1474
1475 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1476 {
1477   SilcSKE ske = fsm_context;
1478   SilcSKEStatus status;
1479   SilcSKEKEPayload payload;
1480   SilcMPInt *KEY;
1481   SilcBuffer packet_buf = &ske->packet->buffer;
1482
1483   SILC_LOG_DEBUG(("Start"));
1484
1485   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1486     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1487     silc_ske_install_retransmission(ske);
1488     silc_packet_free(ske->packet);
1489     ske->packet = NULL;
1490     return SILC_FSM_WAIT;
1491   }
1492
1493   /* Decode the payload */
1494   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1495   if (status != SILC_SKE_STATUS_OK) {
1496     /** Error decoding KE payload */
1497     silc_packet_free(ske->packet);
1498     ske->packet = NULL;
1499     ske->status = status;
1500     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1501     return SILC_FSM_CONTINUE;
1502   }
1503   silc_packet_free(ske->packet);
1504   ske->packet = NULL;
1505   ske->ke2_payload = payload;
1506
1507   if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1508     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1509                     "even though we require it"));
1510     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1511     goto err;
1512   }
1513
1514   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1515
1516   /* Compute the shared secret key */
1517   KEY = silc_calloc(1, sizeof(*KEY));
1518   silc_mp_init(KEY);
1519   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1520   ske->KEY = KEY;
1521
1522   /* Decode the remote's public key */
1523   if (payload->pk_data &&
1524       !silc_pkcs_public_key_alloc(payload->pk_type,
1525                                   payload->pk_data, payload->pk_len,
1526                                   &ske->prop->public_key)) {
1527     SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1528     status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1529     goto err;
1530   }
1531
1532   if (ske->prop->public_key && (ske->callbacks->verify_key ||
1533                                 ske->repository)) {
1534     SILC_LOG_DEBUG(("Verifying public key"));
1535
1536     /** Waiting public key verification */
1537     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1538
1539     /* If repository is provided, verify the key from there. */
1540     if (ske->repository) {
1541       SilcSKRFind find;
1542
1543       find = silc_skr_find_alloc();
1544       if (!find) {
1545         status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1546         goto err;
1547       }
1548       silc_skr_find_set_pkcs_type(find,
1549                                   silc_pkcs_get_type(ske->prop->public_key));
1550       silc_skr_find_set_public_key(find, ske->prop->public_key);
1551       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1552
1553       /* Find key from repository */
1554       SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1555                                   silc_ske_skr_callback, ske));
1556     } else {
1557       /* Verify from application */
1558       SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1559                                                ske->callbacks->context,
1560                                                silc_ske_pk_verified, NULL));
1561     }
1562     /* NOT REACHED */
1563   }
1564
1565   /** Process key material */
1566   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1567   return SILC_FSM_CONTINUE;
1568
1569  err:
1570   silc_ske_payload_ke_free(payload);
1571   ske->ke2_payload = NULL;
1572
1573   silc_mp_uninit(ske->KEY);
1574   silc_free(ske->KEY);
1575   ske->KEY = NULL;
1576
1577   if (status == SILC_SKE_STATUS_OK)
1578     return SILC_SKE_STATUS_ERROR;
1579
1580   /** Error */
1581   ske->status = status;
1582   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1583   return SILC_FSM_CONTINUE;
1584 }
1585
1586 /* Process key material */
1587
1588 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1589 {
1590   SilcSKE ske = fsm_context;
1591   SilcSKEStatus status;
1592   SilcSKEKEPayload payload;
1593   unsigned char hash[SILC_HASH_MAXLEN];
1594   SilcUInt32 hash_len;
1595   int key_len, block_len;
1596
1597   if (ske->aborted) {
1598     /** Aborted */
1599     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1600     return SILC_FSM_CONTINUE;
1601   }
1602
1603   /* Check result of public key verification */
1604   if (ske->status != SILC_SKE_STATUS_OK) {
1605     /** Public key not verified */
1606     SILC_LOG_DEBUG(("Public key verification failed"));
1607     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1608     return SILC_FSM_CONTINUE;
1609   }
1610
1611   payload = ske->ke2_payload;
1612
1613   if (ske->prop->public_key) {
1614     SILC_LOG_DEBUG(("Public key is authentic"));
1615
1616     /* Compute the hash value */
1617     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1618     if (status != SILC_SKE_STATUS_OK)
1619       goto err;
1620
1621     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1622
1623     /* Verify signature */
1624     if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1625                           payload->sign_len, hash, hash_len, NULL)) {
1626       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1627       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1628       goto err;
1629     }
1630
1631     SILC_LOG_DEBUG(("Signature is Ok"));
1632
1633     ske->hash = silc_memdup(hash, hash_len);
1634     ske->hash_len = hash_len;
1635     memset(hash, 'F', hash_len);
1636   }
1637
1638   ske->status = SILC_SKE_STATUS_OK;
1639
1640   /* In case we are doing rekey move to finish it.  */
1641   if (ske->rekey) {
1642     /** Finish rekey */
1643     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1644     return SILC_FSM_CONTINUE;
1645   }
1646
1647   /* Process key material */
1648   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1649   block_len = silc_cipher_get_block_len(ske->prop->cipher);
1650   hash_len = silc_hash_len(ske->prop->hash);
1651   ske->keymat = silc_ske_process_key_material(ske, block_len,
1652                                               key_len, hash_len,
1653                                               &ske->rekey);
1654   if (!ske->keymat) {
1655     SILC_LOG_ERROR(("Error processing key material"));
1656     status = SILC_SKE_STATUS_ERROR;
1657     goto err;
1658   }
1659
1660   /* Send SUCCESS packet */
1661   SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1662   if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1663     /** Error sending packet */
1664     SILC_LOG_DEBUG(("Error sending packet"));
1665     ske->status = SILC_SKE_STATUS_ERROR;
1666     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1667     return SILC_FSM_CONTINUE;
1668   }
1669
1670   /** Waiting completion */
1671   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1672   return SILC_FSM_WAIT;
1673
1674  err:
1675   memset(hash, 'F', sizeof(hash));
1676   silc_ske_payload_ke_free(payload);
1677   ske->ke2_payload = NULL;
1678
1679   silc_mp_uninit(ske->KEY);
1680   silc_free(ske->KEY);
1681   ske->KEY = NULL;
1682
1683   if (ske->hash) {
1684     memset(ske->hash, 'F', hash_len);
1685     silc_free(ske->hash);
1686     ske->hash = NULL;
1687   }
1688
1689   if (status == SILC_SKE_STATUS_OK)
1690     status = SILC_SKE_STATUS_ERROR;
1691
1692   /** Error */
1693   ske->status = status;
1694   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1695   return SILC_FSM_CONTINUE;
1696 }
1697
1698 /* Protocol completed */
1699
1700 SILC_FSM_STATE(silc_ske_st_initiator_end)
1701 {
1702   SilcSKE ske = fsm_context;
1703
1704   SILC_LOG_DEBUG(("Start"));
1705
1706   if (ske->packet->type != SILC_PACKET_SUCCESS) {
1707     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1708     silc_ske_install_retransmission(ske);
1709     silc_packet_free(ske->packet);
1710     ske->packet = NULL;
1711     return SILC_FSM_WAIT;
1712   }
1713
1714   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1715
1716   silc_packet_free(ske->packet);
1717   ske->packet = NULL;
1718   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1719   silc_schedule_task_del_by_context(ske->schedule, ske);
1720
1721   /* Call completion */
1722   silc_ske_completion(ske);
1723
1724   return SILC_FSM_FINISH;
1725 }
1726
1727 /* Aborted by application */
1728
1729 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1730 {
1731   SilcSKE ske = fsm_context;
1732   unsigned char data[4];
1733
1734   SILC_LOG_DEBUG(("Aborted by caller"));
1735
1736   /* Send FAILURE packet */
1737   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1738   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1739
1740   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1741   silc_schedule_task_del_by_context(ske->schedule, ske);
1742
1743   /* Call completion */
1744   silc_ske_completion(ske);
1745
1746   return SILC_FSM_FINISH;
1747 }
1748
1749 /* Error occurred.  Send error to remote host */
1750
1751 SILC_FSM_STATE(silc_ske_st_initiator_error)
1752 {
1753   SilcSKE ske = fsm_context;
1754   SilcSKEStatus status;
1755   unsigned char data[4];
1756
1757   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1758                   silc_ske_map_status(ske->status), ske->status));
1759
1760   status = ske->status;
1761   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1762     status = SILC_SKE_STATUS_ERROR;
1763
1764   /* Send FAILURE packet */
1765   SILC_PUT32_MSB((SilcUInt32)status, data);
1766   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1767
1768   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1769   silc_schedule_task_del_by_context(ske->schedule, ske);
1770
1771   /* Call completion */
1772   silc_ske_completion(ske);
1773
1774   return SILC_FSM_FINISH;
1775 }
1776
1777 /* Failure received from remote */
1778
1779 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1780 {
1781   SilcSKE ske = fsm_context;
1782   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1783
1784   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1785                   silc_ske_map_status(ske->status), ske->status));
1786
1787   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1788     SILC_GET32_MSB(error, ske->packet->buffer.data);
1789     ske->status = error;
1790     silc_packet_free(ske->packet);
1791     ske->packet = NULL;
1792   }
1793
1794   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1795   silc_schedule_task_del_by_context(ske->schedule, ske);
1796
1797   /* Call completion */
1798   silc_ske_completion(ske);
1799
1800   return SILC_FSM_FINISH;
1801 }
1802
1803 /* Starts the protocol as initiator */
1804
1805 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1806                                       SilcPacketStream stream,
1807                                       SilcSKEParams params,
1808                                       SilcSKEStartPayload start_payload)
1809 {
1810   SILC_LOG_DEBUG(("Start SKE as initiator"));
1811
1812   if (!ske || !stream || !params || !params->version)
1813     return NULL;
1814
1815   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1816     return NULL;
1817
1818   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1819     return NULL;
1820
1821   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1822     ske->session_port = params->session_port;
1823
1824   /* Generate security properties if not provided */
1825   if (!start_payload) {
1826     start_payload = silc_ske_assemble_security_properties(ske,
1827                                                           params->flags,
1828                                                           params->version);
1829     if (!start_payload)
1830       return NULL;
1831   }
1832
1833   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1834   ske->start_payload = start_payload;
1835   ske->version = params->version;
1836   ske->running = TRUE;
1837
1838   /* Link to packet stream to get key exchange packets */
1839   ske->stream = stream;
1840   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1841                           SILC_PACKET_KEY_EXCHANGE,
1842                           SILC_PACKET_KEY_EXCHANGE_2,
1843                           SILC_PACKET_SUCCESS,
1844                           SILC_PACKET_FAILURE, -1);
1845
1846   /* Start SKE as initiator */
1847   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1848
1849   return &ske->op;
1850 }
1851
1852 /******************************** Responder *********************************/
1853
1854 /* Start protocol as responder.  Wait initiator's start payload */
1855
1856 SILC_FSM_STATE(silc_ske_st_responder_start)
1857 {
1858   SilcSKE ske = fsm_context;
1859
1860   SILC_LOG_DEBUG(("Start"));
1861
1862   if (ske->aborted) {
1863     /** Aborted */
1864     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1865     return SILC_FSM_CONTINUE;
1866   }
1867
1868   /* Add key exchange timeout */
1869   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1870                                  ske, ske->timeout, 0);
1871
1872   /** Wait for initiator */
1873   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1874   return SILC_FSM_WAIT;
1875 }
1876
1877 /* Decode initiator's start payload.  Select the security properties from
1878    the initiator's start payload and send our reply start payload back. */
1879
1880 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1881 {
1882   SilcSKE ske = fsm_context;
1883   SilcSKEStatus status;
1884   SilcSKEStartPayload remote_payload = NULL;
1885   SilcBuffer packet_buf = &ske->packet->buffer;
1886
1887   SILC_LOG_DEBUG(("Start"));
1888
1889   /* Decode the payload */
1890   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1891   if (status != SILC_SKE_STATUS_OK) {
1892     /** Error decoding Start Payload */
1893     silc_packet_free(ske->packet);
1894     ske->packet = NULL;
1895     ske->status = status;
1896     silc_fsm_next(fsm, silc_ske_st_responder_error);
1897     return SILC_FSM_CONTINUE;
1898   }
1899
1900   /* Take a copy of the payload buffer for future use. It is used to
1901      compute the HASH value. */
1902   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1903
1904   silc_packet_free(ske->packet);
1905   ske->packet = NULL;
1906
1907   /* Force the mutual authentication flag if we want to do it. */
1908   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1909     SILC_LOG_DEBUG(("Force mutual authentication"));
1910     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1911   }
1912
1913   /* Force PFS flag if we require it */
1914   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1915     SILC_LOG_DEBUG(("Force PFS"));
1916     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1917   }
1918
1919   /* Disable IV Included flag if requested */
1920   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1921       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1922     SILC_LOG_DEBUG(("We do not support IV Included flag"));
1923     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1924   }
1925
1926   /* Check and select security properties */
1927   status = silc_ske_select_security_properties(ske, remote_payload,
1928                                                &ske->prop);
1929   if (status != SILC_SKE_STATUS_OK) {
1930     /** Error selecting proposal */
1931     silc_ske_payload_start_free(remote_payload);
1932     ske->status = status;
1933     silc_fsm_next(fsm, silc_ske_st_responder_error);
1934     return SILC_FSM_CONTINUE;
1935   }
1936
1937   silc_ske_payload_start_free(remote_payload);
1938
1939   /* Encode our reply payload to send the selected security properties */
1940   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1941                                          &packet_buf);
1942   if (status != SILC_SKE_STATUS_OK)
1943     goto err;
1944
1945   /* Send the packet. */
1946   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1947                             silc_buffer_data(packet_buf),
1948                             silc_buffer_len(packet_buf)))
1949     goto err;
1950
1951   silc_buffer_free(packet_buf);
1952
1953   /** Waiting initiator's KE payload */
1954   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1955   return SILC_FSM_WAIT;
1956
1957  err:
1958   if (ske->prop->group)
1959     silc_ske_group_free(ske->prop->group);
1960   if (ske->prop->cipher)
1961     silc_cipher_free(ske->prop->cipher);
1962   if (ske->prop->hash)
1963     silc_hash_free(ske->prop->hash);
1964   if (ske->prop->hmac)
1965     silc_hmac_free(ske->prop->hmac);
1966   silc_free(ske->prop);
1967   ske->prop = NULL;
1968
1969   if (status == SILC_SKE_STATUS_OK)
1970     status = SILC_SKE_STATUS_ERROR;
1971
1972   /** Error */
1973   ske->status = status;
1974   silc_fsm_next(fsm, silc_ske_st_responder_error);
1975   return SILC_FSM_CONTINUE;
1976 }
1977
1978 /* Phase-2.  Decode initiator's KE payload */
1979
1980 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1981 {
1982   SilcSKE ske = fsm_context;
1983   SilcSKEStatus status;
1984   SilcSKEKEPayload recv_payload;
1985   SilcBuffer packet_buf = &ske->packet->buffer;
1986
1987   SILC_LOG_DEBUG(("Start"));
1988
1989   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1990     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1991     silc_ske_install_retransmission(ske);
1992     silc_packet_free(ske->packet);
1993     ske->packet = NULL;
1994     return SILC_FSM_WAIT;
1995   }
1996
1997   /* Decode Key Exchange Payload */
1998   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1999   if (status != SILC_SKE_STATUS_OK) {
2000     /** Error decoding KE payload */
2001     silc_packet_free(ske->packet);
2002     ske->packet = NULL;
2003     ske->status = status;
2004     silc_fsm_next(fsm, silc_ske_st_responder_error);
2005     return SILC_FSM_CONTINUE;
2006   }
2007
2008   ske->ke1_payload = recv_payload;
2009
2010   silc_packet_free(ske->packet);
2011   ske->packet = NULL;
2012
2013   /* Verify the received public key and verify the signature if we are
2014      doing mutual authentication. */
2015   if (ske->start_payload &&
2016       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2017
2018     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2019
2020     if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2021                                    ske->repository)) {
2022       /** Public key not provided */
2023       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2024                       "certificate), even though we require it"));
2025       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2026       silc_fsm_next(fsm, silc_ske_st_responder_error);
2027       return SILC_FSM_CONTINUE;
2028     }
2029
2030     /* Decode the remote's public key */
2031     if (recv_payload->pk_data &&
2032         !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2033                                     recv_payload->pk_data,
2034                                     recv_payload->pk_len,
2035                                     &ske->prop->public_key)) {
2036       /** Error decoding public key */
2037       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2038       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2039       silc_fsm_next(fsm, silc_ske_st_responder_error);
2040       return SILC_FSM_CONTINUE;
2041     }
2042
2043     if (ske->prop->public_key && (ske->callbacks->verify_key ||
2044                                   ske->repository)) {
2045       SILC_LOG_DEBUG(("Verifying public key"));
2046
2047       /** Waiting public key verification */
2048       silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2049
2050       /* If repository is provided, verify the key from there. */
2051       if (ske->repository) {
2052         SilcSKRFind find;
2053
2054         find = silc_skr_find_alloc();
2055         if (!find) {
2056           ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2057           silc_fsm_next(fsm, silc_ske_st_responder_error);
2058           return SILC_FSM_CONTINUE;
2059         }
2060         silc_skr_find_set_pkcs_type(find,
2061                                     silc_pkcs_get_type(ske->prop->public_key));
2062         silc_skr_find_set_public_key(find, ske->prop->public_key);
2063         silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2064
2065         /* Find key from repository */
2066         SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2067                                     silc_ske_skr_callback, ske));
2068       } else {
2069         /* Verify from application */
2070         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2071                                                  ske->callbacks->context,
2072                                                  silc_ske_pk_verified, NULL));
2073       }
2074       /* NOT REACHED */
2075     }
2076   }
2077
2078   /** Generate KE2 payload */
2079   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2080   return SILC_FSM_CONTINUE;
2081 }
2082
2083 /* Phase-4. Generate KE2 payload */
2084
2085 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2086 {
2087   SilcSKE ske = fsm_context;
2088   SilcSKEStatus status;
2089   SilcSKEKEPayload recv_payload, send_payload;
2090   SilcMPInt *x, *KEY;
2091
2092   if (ske->aborted) {
2093     /** Aborted */
2094     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2095     return SILC_FSM_CONTINUE;
2096   }
2097
2098   /* Check result of public key verification */
2099   if (ske->status != SILC_SKE_STATUS_OK) {
2100     /** Public key not verified */
2101     SILC_LOG_DEBUG(("Public key verification failed"));
2102     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2103     return SILC_FSM_CONTINUE;
2104   }
2105
2106   recv_payload = ske->ke1_payload;
2107
2108   /* The public key verification was performed only if the Mutual
2109      Authentication flag is set. */
2110   if (ske->start_payload &&
2111       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2112     unsigned char hash[SILC_HASH_MAXLEN];
2113     SilcUInt32 hash_len;
2114
2115     SILC_LOG_DEBUG(("Public key is authentic"));
2116
2117     /* Compute the hash value */
2118     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2119     if (status != SILC_SKE_STATUS_OK) {
2120       /** Error computing hash */
2121       ske->status = status;
2122       silc_fsm_next(fsm, silc_ske_st_responder_error);
2123       return SILC_FSM_CONTINUE;
2124     }
2125
2126     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2127
2128     /* Verify signature */
2129     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2130                           recv_payload->sign_len, hash, hash_len, NULL)) {
2131       /** Incorrect signature */
2132       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2133       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2134       silc_fsm_next(fsm, silc_ske_st_responder_error);
2135       return SILC_FSM_CONTINUE;
2136     }
2137
2138     SILC_LOG_DEBUG(("Signature is Ok"));
2139
2140     memset(hash, 'F', hash_len);
2141   }
2142
2143   /* Create the random number x, 1 < x < q. */
2144   x = silc_calloc(1, sizeof(*x));
2145   silc_mp_init(x);
2146   status =
2147     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2148                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2149                         x);
2150   if (status != SILC_SKE_STATUS_OK) {
2151     /** Error generating random number */
2152     silc_mp_uninit(x);
2153     silc_free(x);
2154     ske->status = status;
2155     silc_fsm_next(fsm, silc_ske_st_responder_error);
2156     return SILC_FSM_CONTINUE;
2157   }
2158
2159   /* Save the results for later processing */
2160   send_payload = silc_calloc(1, sizeof(*send_payload));
2161   ske->x = x;
2162   ske->ke2_payload = send_payload;
2163
2164   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2165
2166   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2167   silc_mp_init(&send_payload->x);
2168   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2169                   &ske->prop->group->group);
2170
2171   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2172
2173   /* Compute the shared secret key */
2174   KEY = silc_calloc(1, sizeof(*KEY));
2175   silc_mp_init(KEY);
2176   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2177                   &ske->prop->group->group);
2178   ske->KEY = KEY;
2179
2180   /** Send KE2 payload */
2181   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2182   return SILC_FSM_CONTINUE;
2183 }
2184
2185 /* Phase-5.  Send KE2 payload */
2186
2187 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2188 {
2189   SilcSKE ske = fsm_context;
2190   SilcSKEStatus status;
2191   SilcBuffer payload_buf;
2192   unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2193   SilcUInt32 hash_len, sign_len, pk_len;
2194
2195   SILC_LOG_DEBUG(("Start"));
2196
2197   if (ske->public_key && ske->private_key) {
2198     SILC_LOG_DEBUG(("Getting public key"));
2199
2200     /* Get the public key */
2201     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2202     if (!pk) {
2203       /** Error encoding public key */
2204       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2205       silc_fsm_next(fsm, silc_ske_st_responder_error);
2206       return SILC_FSM_CONTINUE;
2207     }
2208     ske->ke2_payload->pk_data = pk;
2209     ske->ke2_payload->pk_len = pk_len;
2210
2211     SILC_LOG_DEBUG(("Computing HASH value"));
2212
2213     /* Compute the hash value */
2214     memset(hash, 0, sizeof(hash));
2215     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2216     if (status != SILC_SKE_STATUS_OK) {
2217       /** Error computing hash */
2218       ske->status = status;
2219       silc_fsm_next(fsm, silc_ske_st_responder_error);
2220       return SILC_FSM_CONTINUE;
2221     }
2222
2223     ske->hash = silc_memdup(hash, hash_len);
2224     ske->hash_len = hash_len;
2225
2226     SILC_LOG_DEBUG(("Signing HASH value"));
2227
2228     /* Sign the hash value */
2229     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2230                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2231       /** Error computing signature */
2232       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2233       silc_fsm_next(fsm, silc_ske_st_responder_error);
2234       return SILC_FSM_CONTINUE;
2235     }
2236     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2237     ske->ke2_payload->sign_len = sign_len;
2238     memset(sign, 0, sizeof(sign));
2239   }
2240   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2241
2242   /* Encode the Key Exchange Payload */
2243   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2244                                       &payload_buf);
2245   if (status != SILC_SKE_STATUS_OK) {
2246     /** Error encoding KE payload */
2247     ske->status = status;
2248     silc_fsm_next(fsm, silc_ske_st_responder_error);
2249     return SILC_FSM_CONTINUE;
2250   }
2251
2252   /* Send the packet. */
2253   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2254                             payload_buf->data, silc_buffer_len(payload_buf))) {
2255     SILC_LOG_DEBUG(("Error sending packet"));
2256     ske->status = SILC_SKE_STATUS_ERROR;
2257     silc_fsm_next(fsm, silc_ske_st_responder_error);
2258     return SILC_FSM_CONTINUE;
2259   }
2260
2261   silc_buffer_free(payload_buf);
2262
2263   /** Waiting completion */
2264   silc_fsm_next(fsm, silc_ske_st_responder_end);
2265   return SILC_FSM_WAIT;
2266 }
2267
2268 /* Protocol completed */
2269
2270 SILC_FSM_STATE(silc_ske_st_responder_end)
2271 {
2272   SilcSKE ske = fsm_context;
2273   unsigned char tmp[4];
2274   SilcUInt32 hash_len, key_len, block_len;
2275
2276   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2277     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2278     silc_ske_install_retransmission(ske);
2279     silc_packet_free(ske->packet);
2280     ske->packet = NULL;
2281     return SILC_FSM_WAIT;
2282   }
2283   silc_packet_free(ske->packet);
2284   ske->packet = NULL;
2285
2286   /* Process key material */
2287   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2288   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2289   hash_len = silc_hash_len(ske->prop->hash);
2290   ske->keymat = silc_ske_process_key_material(ske, block_len,
2291                                               key_len, hash_len,
2292                                               &ske->rekey);
2293   if (!ske->keymat) {
2294     /** Error processing key material */
2295     ske->status = SILC_SKE_STATUS_ERROR;
2296     silc_fsm_next(fsm, silc_ske_st_responder_error);
2297     return SILC_FSM_CONTINUE;
2298   }
2299
2300   /* Send SUCCESS packet */
2301   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2302   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2303
2304   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2305   silc_schedule_task_del_by_context(ske->schedule, ske);
2306
2307   /* Call completion */
2308   silc_ske_completion(ske);
2309
2310   return SILC_FSM_FINISH;
2311 }
2312
2313 /* Aborted by application */
2314
2315 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2316 {
2317   SilcSKE ske = fsm_context;
2318   unsigned char tmp[4];
2319
2320   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2321
2322   /* Send FAILURE packet */
2323   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2324   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2325
2326   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2327   silc_schedule_task_del_by_context(ske->schedule, ske);
2328
2329   /* Call completion */
2330   silc_ske_completion(ske);
2331
2332   return SILC_FSM_FINISH;
2333 }
2334
2335 /* Failure received from remote */
2336
2337 SILC_FSM_STATE(silc_ske_st_responder_failure)
2338 {
2339   SilcSKE ske = fsm_context;
2340   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2341
2342   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2343
2344   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2345     SILC_GET32_MSB(error, ske->packet->buffer.data);
2346     ske->status = error;
2347     silc_packet_free(ske->packet);
2348     ske->packet = NULL;
2349   }
2350
2351   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2352   silc_schedule_task_del_by_context(ske->schedule, ske);
2353
2354   /* Call completion */
2355   silc_ske_completion(ske);
2356
2357   return SILC_FSM_FINISH;
2358 }
2359
2360 /* Error occurred */
2361
2362 SILC_FSM_STATE(silc_ske_st_responder_error)
2363 {
2364   SilcSKE ske = fsm_context;
2365   unsigned char tmp[4];
2366
2367   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2368                   ske->status, silc_ske_map_status(ske->status)));
2369
2370   /* Send FAILURE packet */
2371   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2372     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2373   SILC_PUT32_MSB(ske->status, tmp);
2374   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2375
2376   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2377   silc_schedule_task_del_by_context(ske->schedule, ske);
2378
2379   /* Call completion */
2380   silc_ske_completion(ske);
2381
2382   return SILC_FSM_FINISH;
2383 }
2384
2385 /* Starts the protocol as responder. */
2386
2387 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2388                                       SilcPacketStream stream,
2389                                       SilcSKEParams params)
2390 {
2391   SILC_LOG_DEBUG(("Start SKE as responder"));
2392
2393   if (!ske || !stream || !params || !params->version)
2394     return NULL;
2395
2396   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2397     return NULL;
2398
2399   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2400     return NULL;
2401
2402   ske->responder = TRUE;
2403   ske->flags = params->flags;
2404   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2405   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2406     ske->session_port = params->session_port;
2407   ske->version = strdup(params->version);
2408   if (!ske->version)
2409     return NULL;
2410   ske->running = TRUE;
2411
2412   /* Link to packet stream to get key exchange packets */
2413   ske->stream = stream;
2414   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2415                           SILC_PACKET_KEY_EXCHANGE,
2416                           SILC_PACKET_KEY_EXCHANGE_1,
2417                           SILC_PACKET_SUCCESS,
2418                           SILC_PACKET_FAILURE, -1);
2419
2420   /* Start SKE as responder */
2421   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2422
2423   return &ske->op;
2424 }
2425
2426 /***************************** Initiator Rekey ******************************/
2427
2428 /* Start rekey */
2429
2430 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2431 {
2432   SilcSKE ske = fsm_context;
2433   SilcStatus status;
2434
2435   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2436
2437   if (ske->aborted) {
2438     /** Aborted */
2439     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2440     return SILC_FSM_CONTINUE;
2441   }
2442
2443   /* Add rekey exchange timeout */
2444   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2445                                  ske, 30, 0);
2446
2447   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2448   if (!ske->prop) {
2449     /** No memory */
2450     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2451     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2452     return SILC_FSM_CONTINUE;
2453   }
2454
2455   /* Send REKEY packet to start rekey protocol */
2456   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2457     /** Error sending packet */
2458     SILC_LOG_DEBUG(("Error sending packet"));
2459     ske->status = SILC_SKE_STATUS_ERROR;
2460     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2461     return SILC_FSM_CONTINUE;
2462   }
2463
2464   /* If doing rekey without PFS, move directly to the end of the protocol. */
2465   if (!ske->rekey->pfs) {
2466     /** Rekey without PFS */
2467     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2468     return SILC_FSM_CONTINUE;
2469   }
2470
2471   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2472                                         &ske->prop->group);
2473   if (status != SILC_SKE_STATUS_OK) {
2474     /** Unknown group */
2475     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2476     return SILC_FSM_CONTINUE;
2477   }
2478
2479   /** Rekey with PFS */
2480   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2481   return SILC_FSM_CONTINUE;
2482 }
2483
2484 /* Sends REKEY_DONE packet to finish the protocol. */
2485
2486 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2487 {
2488   SilcSKE ske = fsm_context;
2489   SilcCipher send_key;
2490   SilcHmac hmac_send;
2491   SilcHash hash;
2492   SilcUInt32 key_len, block_len, hash_len, x_len;
2493   unsigned char *pfsbuf;
2494
2495   SILC_LOG_DEBUG(("Start"));
2496
2497   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2498   key_len = silc_cipher_get_key_len(send_key);
2499   block_len = silc_cipher_get_block_len(send_key);
2500
2501   if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2502     /** Cannot allocate hash */
2503     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2504     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2505     return SILC_FSM_CONTINUE;
2506   }
2507   hash_len = silc_hash_len(hash);
2508
2509   /* Process key material */
2510   if (ske->rekey->pfs) {
2511     /* PFS */
2512     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2513     if (pfsbuf) {
2514       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2515                                                        block_len, key_len,
2516                                                        hash_len, hash);
2517       memset(pfsbuf, 0, x_len);
2518       silc_free(pfsbuf);
2519     }
2520   } else {
2521     /* No PFS */
2522     ske->keymat =
2523       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2524                                          ske->rekey->enc_key_len / 8,
2525                                          block_len, key_len,
2526                                          hash_len, hash);
2527   }
2528
2529   if (!ske->keymat) {
2530     SILC_LOG_ERROR(("Error processing key material"));
2531     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2532     return SILC_FSM_CONTINUE;
2533   }
2534
2535   ske->prop->cipher = send_key;
2536   ske->prop->hmac = hmac_send;
2537   ske->prop->hash = hash;
2538
2539   /* Get sending keys */
2540   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2541                          &hmac_send, NULL, NULL)) {
2542     /** Cannot get keys */
2543     ske->status = SILC_SKE_STATUS_ERROR;
2544     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2545     return SILC_FSM_CONTINUE;
2546   }
2547
2548   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2549      packet sent after this call will be protected with the new keys. */
2550   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2551                             TRUE)) {
2552     /** Cannot set keys */
2553     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2554     ske->status = SILC_SKE_STATUS_ERROR;
2555     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2556     return SILC_FSM_CONTINUE;
2557   }
2558
2559   /** Wait for REKEY_DONE */
2560   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2561   return SILC_FSM_WAIT;
2562 }
2563
2564 /* Rekey protocol end */
2565
2566 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2567 {
2568   SilcSKE ske = fsm_context;
2569   SilcCipher receive_key;
2570   SilcHmac hmac_receive;
2571   SilcSKERekeyMaterial rekey;
2572
2573   SILC_LOG_DEBUG(("Start"));
2574
2575   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2576     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2577     silc_packet_free(ske->packet);
2578     ske->packet = NULL;
2579     return SILC_FSM_WAIT;
2580   }
2581
2582   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2583   ske->prop->cipher = receive_key;
2584   ske->prop->hmac = hmac_receive;
2585
2586   /* Get receiving keys */
2587   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2588                          NULL, &hmac_receive, NULL)) {
2589     /** Cannot get keys */
2590     ske->status = SILC_SKE_STATUS_ERROR;
2591     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2592     return SILC_FSM_CONTINUE;
2593   }
2594
2595   /* Set new receiving keys into use.  All packets received after this will
2596      be decrypted with the new keys. */
2597   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2598                             hmac_receive, FALSE)) {
2599     /** Cannot set keys */
2600     SILC_LOG_DEBUG(("Cannot set new keys"));
2601     ske->status = SILC_SKE_STATUS_ERROR;
2602     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2603     return SILC_FSM_CONTINUE;
2604   }
2605
2606   SILC_LOG_DEBUG(("Rekey completed successfully"));
2607
2608   /* Generate new rekey material */
2609   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2610   if (!rekey) {
2611     /** No memory */
2612     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2613     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2614     return SILC_FSM_CONTINUE;
2615   }
2616   rekey->pfs = ske->rekey->pfs;
2617   ske->rekey = rekey;
2618
2619   ske->prop->cipher = NULL;
2620   ske->prop->hmac = NULL;
2621   silc_packet_free(ske->packet);
2622   ske->packet = NULL;
2623   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2624   silc_schedule_task_del_by_context(ske->schedule, ske);
2625
2626   /* Call completion */
2627   silc_ske_completion(ske);
2628
2629   return SILC_FSM_FINISH;
2630 }
2631
2632 /* Starts rekey protocol as initiator */
2633
2634 SilcAsyncOperation
2635 silc_ske_rekey_initiator(SilcSKE ske,
2636                          SilcPacketStream stream,
2637                          SilcSKERekeyMaterial rekey)
2638 {
2639   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2640
2641   if (!ske || !stream || !rekey)
2642     return NULL;
2643
2644   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2645     return NULL;
2646
2647   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2648     return NULL;
2649
2650   ske->rekey = rekey;
2651   ske->responder = FALSE;
2652   ske->running = TRUE;
2653   ske->rekeying = TRUE;
2654
2655   /* Link to packet stream to get key exchange packets */
2656   ske->stream = stream;
2657   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2658                           SILC_PACKET_REKEY,
2659                           SILC_PACKET_REKEY_DONE,
2660                           SILC_PACKET_KEY_EXCHANGE_2,
2661                           SILC_PACKET_SUCCESS,
2662                           SILC_PACKET_FAILURE, -1);
2663
2664   /* Start SKE rekey as initiator */
2665   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2666
2667   return &ske->op;
2668 }
2669
2670 /***************************** Responder Rekey ******************************/
2671
2672 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2673
2674 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2675 {
2676   return SILC_FSM_FINISH;
2677 }
2678
2679 /* Starts rekey protocol as responder */
2680
2681 SilcAsyncOperation
2682 silc_ske_rekey_responder(SilcSKE ske,
2683                          SilcPacketStream stream,
2684                          SilcSKERekeyMaterial rekey)
2685 {
2686   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2687
2688   if (!ske || !stream || !rekey)
2689     return NULL;
2690
2691   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2692     return NULL;
2693
2694   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2695     return NULL;
2696
2697   ske->rekey = rekey;
2698   ske->responder = TRUE;
2699   ske->running = TRUE;
2700   ske->rekeying = TRUE;
2701
2702   /* Link to packet stream to get key exchange packets */
2703   ske->stream = stream;
2704   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2705                           SILC_PACKET_REKEY,
2706                           SILC_PACKET_REKEY_DONE,
2707                           SILC_PACKET_KEY_EXCHANGE_1,
2708                           SILC_PACKET_SUCCESS,
2709                           SILC_PACKET_FAILURE, -1);
2710
2711   /* Start SKE rekey as responder */
2712   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2713
2714   return &ske->op;
2715 }
2716
2717 /* Processes the provided key material `data' as the SILC protocol
2718    specification defines. */
2719
2720 SilcSKEKeyMaterial
2721 silc_ske_process_key_material_data(unsigned char *data,
2722                                    SilcUInt32 data_len,
2723                                    SilcUInt32 req_iv_len,
2724                                    SilcUInt32 req_enc_key_len,
2725                                    SilcUInt32 req_hmac_key_len,
2726                                    SilcHash hash)
2727 {
2728   SilcBuffer buf;
2729   unsigned char hashd[SILC_HASH_MAXLEN];
2730   SilcUInt32 hash_len = req_hmac_key_len;
2731   SilcUInt32 enc_key_len = req_enc_key_len / 8;
2732   SilcSKEKeyMaterial key;
2733
2734   SILC_LOG_DEBUG(("Start"));
2735
2736   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2737     return NULL;
2738
2739   key = silc_calloc(1, sizeof(*key));
2740   if (!key)
2741     return NULL;
2742
2743   buf = silc_buffer_alloc_size(1 + data_len);
2744   if (!buf)
2745     return NULL;
2746   silc_buffer_format(buf,
2747                      SILC_STR_UI_CHAR(0),
2748                      SILC_STR_UI_XNSTRING(data, data_len),
2749                      SILC_STR_END);
2750
2751   /* Take IVs */
2752   memset(hashd, 0, sizeof(hashd));
2753   buf->data[0] = 0;
2754   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2755   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2756   memcpy(key->send_iv, hashd, req_iv_len);
2757   memset(hashd, 0, sizeof(hashd));
2758   buf->data[0] = 1;
2759   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2760   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2761   memcpy(key->receive_iv, hashd, req_iv_len);
2762   key->iv_len = req_iv_len;
2763
2764   /* Take the encryption keys. If requested key size is more than
2765      the size of hash length we will distribute more key material
2766      as protocol defines. */
2767   buf->data[0] = 2;
2768   if (enc_key_len > hash_len) {
2769     SilcBuffer dist;
2770     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2771         k3[SILC_HASH_MAXLEN];
2772     unsigned char *dtmp;
2773
2774     /* XXX */
2775     if (enc_key_len > (3 * hash_len))
2776       return NULL;
2777
2778     /* Take first round */
2779     memset(k1, 0, sizeof(k1));
2780     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2781
2782     /* Take second round */
2783     dist = silc_buffer_alloc_size(data_len + hash_len);
2784     if (!dist)
2785       return NULL;
2786     silc_buffer_format(dist,
2787                        SILC_STR_UI_XNSTRING(data, data_len),
2788                        SILC_STR_UI_XNSTRING(k1, hash_len),
2789                        SILC_STR_END);
2790     memset(k2, 0, sizeof(k2));
2791     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2792
2793     /* Take third round */
2794     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2795     silc_buffer_pull_tail(dist, hash_len);
2796     silc_buffer_pull(dist, data_len + hash_len);
2797     silc_buffer_format(dist,
2798                        SILC_STR_UI_XNSTRING(k2, hash_len),
2799                        SILC_STR_END);
2800     silc_buffer_push(dist, data_len + hash_len);
2801     memset(k3, 0, sizeof(k3));
2802     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2803
2804     /* Then, save the keys */
2805     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2806     memcpy(dtmp, k1, hash_len);
2807     memcpy(dtmp + hash_len, k2, hash_len);
2808     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2809
2810     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2811     memcpy(key->send_enc_key, dtmp, enc_key_len);
2812     key->enc_key_len = req_enc_key_len;
2813
2814     memset(dtmp, 0, (3 * hash_len));
2815     memset(k1, 0, sizeof(k1));
2816     memset(k2, 0, sizeof(k2));
2817     memset(k3, 0, sizeof(k3));
2818     silc_free(dtmp);
2819     silc_buffer_clear(dist);
2820     silc_buffer_free(dist);
2821   } else {
2822     /* Take normal hash as key */
2823     memset(hashd, 0, sizeof(hashd));
2824     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2825     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2826     memcpy(key->send_enc_key, hashd, enc_key_len);
2827     key->enc_key_len = req_enc_key_len;
2828   }
2829
2830   buf->data[0] = 3;
2831   if (enc_key_len > hash_len) {
2832     SilcBuffer dist;
2833     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2834         k3[SILC_HASH_MAXLEN];
2835     unsigned char *dtmp;
2836
2837     /* XXX */
2838     if (enc_key_len > (3 * hash_len))
2839       return NULL;
2840
2841     /* Take first round */
2842     memset(k1, 0, sizeof(k1));
2843     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2844
2845     /* Take second round */
2846     dist = silc_buffer_alloc_size(data_len + hash_len);
2847     if (!dist)
2848       return NULL;
2849     silc_buffer_format(dist,
2850                        SILC_STR_UI_XNSTRING(data, data_len),
2851                        SILC_STR_UI_XNSTRING(k1, hash_len),
2852                        SILC_STR_END);
2853     memset(k2, 0, sizeof(k2));
2854     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2855
2856     /* Take third round */
2857     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2858     silc_buffer_pull_tail(dist, hash_len);
2859     silc_buffer_pull(dist, data_len + hash_len);
2860     silc_buffer_format(dist,
2861                        SILC_STR_UI_XNSTRING(k2, hash_len),
2862                        SILC_STR_END);
2863     silc_buffer_push(dist, data_len + hash_len);
2864     memset(k3, 0, sizeof(k3));
2865     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2866
2867     /* Then, save the keys */
2868     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2869     memcpy(dtmp, k1, hash_len);
2870     memcpy(dtmp + hash_len, k2, hash_len);
2871     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2872
2873     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2874     memcpy(key->receive_enc_key, dtmp, enc_key_len);
2875     key->enc_key_len = req_enc_key_len;
2876
2877     memset(dtmp, 0, (3 * hash_len));
2878     memset(k1, 0, sizeof(k1));
2879     memset(k2, 0, sizeof(k2));
2880     memset(k3, 0, sizeof(k3));
2881     silc_free(dtmp);
2882     silc_buffer_clear(dist);
2883     silc_buffer_free(dist);
2884   } else {
2885     /* Take normal hash as key */
2886     memset(hashd, 0, sizeof(hashd));
2887     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2888     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2889     memcpy(key->receive_enc_key, hashd, enc_key_len);
2890     key->enc_key_len = req_enc_key_len;
2891   }
2892
2893   /* Take HMAC keys */
2894   memset(hashd, 0, sizeof(hashd));
2895   buf->data[0] = 4;
2896   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2897   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2898   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2899   memset(hashd, 0, sizeof(hashd));
2900   buf->data[0] = 5;
2901   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2902   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2903   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2904   key->hmac_key_len = req_hmac_key_len;
2905   memset(hashd, 0, sizeof(hashd));
2906
2907   silc_buffer_clear(buf);
2908   silc_buffer_free(buf);
2909
2910   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2911
2912   return key;
2913 }
2914
2915 /* Processes negotiated key material as protocol specifies. This returns
2916    the actual keys to be used in the SILC. */
2917
2918 SilcSKEKeyMaterial
2919 silc_ske_process_key_material(SilcSKE ske,
2920                               SilcUInt32 req_iv_len,
2921                               SilcUInt32 req_enc_key_len,
2922                               SilcUInt32 req_hmac_key_len,
2923                               SilcSKERekeyMaterial *rekey)
2924 {
2925   SilcBuffer buf;
2926   unsigned char *tmpbuf;
2927   SilcUInt32 klen;
2928   SilcSKEKeyMaterial key;
2929
2930   /* Encode KEY to binary data */
2931   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2932
2933   buf = silc_buffer_alloc_size(klen + ske->hash_len);
2934   if (!buf)
2935     return NULL;
2936   silc_buffer_format(buf,
2937                      SILC_STR_UI_XNSTRING(tmpbuf, klen),
2938                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2939                      SILC_STR_END);
2940
2941   /* Process the key material */
2942   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2943                                            req_iv_len, req_enc_key_len,
2944                                            req_hmac_key_len,
2945                                            ske->prop->hash);
2946
2947   memset(tmpbuf, 0, klen);
2948   silc_free(tmpbuf);
2949   silc_buffer_clear(buf);
2950   silc_buffer_free(buf);
2951
2952   if (rekey) {
2953     *rekey = silc_ske_make_rekey_material(ske, key);
2954     if (!(*rekey))
2955       return NULL;
2956   }
2957
2958   return key;
2959 }
2960
2961 /* Free key material structure */
2962
2963 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2964 {
2965   if (!key)
2966     return;
2967
2968   if (key->send_iv)
2969     silc_free(key->send_iv);
2970   if (key->receive_iv)
2971     silc_free(key->receive_iv);
2972   if (key->send_enc_key) {
2973     memset(key->send_enc_key, 0, key->enc_key_len / 8);
2974     silc_free(key->send_enc_key);
2975   }
2976   if (key->receive_enc_key) {
2977     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2978     silc_free(key->receive_enc_key);
2979   }
2980   if (key->send_hmac_key) {
2981     memset(key->send_hmac_key, 0, key->hmac_key_len);
2982     silc_free(key->send_hmac_key);
2983   }
2984   if (key->receive_hmac_key) {
2985     memset(key->receive_hmac_key, 0, key->hmac_key_len);
2986     silc_free(key->receive_hmac_key);
2987   }
2988   silc_free(key);
2989 }
2990
2991 /* Free rekey material */
2992
2993 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2994 {
2995   if (!rekey)
2996     return;
2997   if (rekey->send_enc_key) {
2998     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2999     silc_free(rekey->send_enc_key);
3000   }
3001   silc_free(rekey->hash);
3002   silc_free(rekey);
3003 }
3004
3005 /* Set keys into use */
3006
3007 SilcBool silc_ske_set_keys(SilcSKE ske,
3008                            SilcSKEKeyMaterial keymat,
3009                            SilcSKESecurityProperties prop,
3010                            SilcCipher *ret_send_key,
3011                            SilcCipher *ret_receive_key,
3012                            SilcHmac *ret_hmac_send,
3013                            SilcHmac *ret_hmac_receive,
3014                            SilcHash *ret_hash)
3015 {
3016   unsigned char iv[32];
3017
3018   /* Allocate ciphers to be used in the communication */
3019   if (ret_send_key) {
3020     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3021                            ret_send_key))
3022       return FALSE;
3023   }
3024   if (ret_receive_key) {
3025     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3026                            ret_receive_key))
3027       return FALSE;
3028   }
3029
3030   /* Allocate HMACs */
3031   if (ret_hmac_send) {
3032     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3033                          ret_hmac_send))
3034       return FALSE;
3035   }
3036   if (ret_hmac_receive) {
3037     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3038                          ret_hmac_receive))
3039       return FALSE;
3040   }
3041
3042   /* Set key material */
3043   memset(iv, 0, sizeof(iv));
3044   if (ske->responder) {
3045     if (ret_send_key) {
3046       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3047                           keymat->enc_key_len, TRUE);
3048
3049       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3050         memcpy(iv, ske->hash, 4);
3051         memcpy(iv + 4, keymat->receive_iv, 4);
3052         silc_cipher_set_iv(*ret_send_key, iv);
3053       } else {
3054         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3055       }
3056     }
3057     if (ret_receive_key) {
3058       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3059                           keymat->enc_key_len, FALSE);
3060
3061       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3062         memcpy(iv, ske->hash, 4);
3063         memcpy(iv + 4, keymat->send_iv, 4);
3064         silc_cipher_set_iv(*ret_receive_key, iv);
3065       } else {
3066         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3067       }
3068     }
3069     if (ret_hmac_send)
3070       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3071                         keymat->hmac_key_len);
3072     if (ret_hmac_receive)
3073       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3074                         keymat->hmac_key_len);
3075   } else {
3076     if (ret_send_key) {
3077       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3078                           keymat->enc_key_len, TRUE);
3079
3080       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3081         memcpy(iv, ske->hash, 4);
3082         memcpy(iv + 4, keymat->send_iv, 4);
3083         silc_cipher_set_iv(*ret_send_key, iv);
3084       } else {
3085         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3086       }
3087     }
3088     if (ret_receive_key) {
3089       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3090                           keymat->enc_key_len, FALSE);
3091
3092       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3093         memcpy(iv, ske->hash, 4);
3094         memcpy(iv + 4, keymat->receive_iv, 4);
3095         silc_cipher_set_iv(*ret_receive_key, iv);
3096       } else {
3097         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3098       }
3099     }
3100     if (ret_hmac_send)
3101       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3102                         keymat->hmac_key_len);
3103     if (ret_hmac_receive)
3104       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3105                         keymat->hmac_key_len);
3106   }
3107
3108   /* Allocate hash */
3109   if (ret_hash) {
3110     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3111       return FALSE;
3112   }
3113
3114   return TRUE;
3115 }
3116
3117 const char *silc_ske_status_string[] =
3118 {
3119   /* Official */
3120   "Ok",
3121   "Unkown error occurred",
3122   "Bad payload in packet",
3123   "Unsupported group",
3124   "Unsupported cipher",
3125   "Unsupported PKCS",
3126   "Unsupported hash function",
3127   "Unsupported HMAC",
3128   "Unsupported public key (or certificate)",
3129   "Incorrect signature",
3130   "Bad or unsupported version",
3131   "Invalid cookie",
3132
3133   /* Other errors */
3134   "Remote did not provide public key",
3135   "Bad reserved field in packet",
3136   "Bad payload length in packet",
3137   "Error computing signature",
3138   "System out of memory",
3139   "Key exchange timeout",
3140
3141   NULL
3142 };
3143
3144 /* Maps status to readable string and returns the string. If string is not
3145    found and empty character string ("") is returned. */
3146
3147 const char *silc_ske_map_status(SilcSKEStatus status)
3148 {
3149   int i;
3150
3151   for (i = 0; silc_ske_status_string[i]; i++)
3152     if (status == i)
3153       return silc_ske_status_string[i];
3154
3155   return "";
3156 }
3157
3158 /* Parses remote host's version string. */
3159
3160 SilcBool silc_ske_parse_version(SilcSKE ske,
3161                                 SilcUInt32 *protocol_version,
3162                                 char **protocol_version_string,
3163                                 SilcUInt32 *software_version,
3164                                 char **software_version_string,
3165                                 char **vendor_version)
3166 {
3167   return silc_parse_version_string(ske->remote_version,
3168                                    protocol_version,
3169                                    protocol_version_string,
3170                                    software_version,
3171                                    software_version_string,
3172                                    vendor_version);
3173 }
3174
3175 /* Get security properties */
3176
3177 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3178 {
3179   return ske->prop;
3180 }
3181
3182 /* Get key material */
3183
3184 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3185 {
3186   return ske->keymat;
3187 }