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