Added SilcAsyncOperation to all SKE initiator/responder functions.
[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 silc_ske_initiator(SilcSKE ske,
1789                                       SilcPacketStream stream,
1790                                       SilcSKEParams params,
1791                                       SilcSKEStartPayload start_payload)
1792 {
1793   SILC_LOG_DEBUG(("Start SKE as initiator"));
1794
1795   if (!ske || !stream || !params || !params->version)
1796     return NULL;
1797
1798   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1799     return NULL;
1800
1801   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1802     return NULL;
1803
1804   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1805     ske->session_port = params->session_port;
1806
1807   /* Generate security properties if not provided */
1808   if (!start_payload) {
1809     start_payload = silc_ske_assemble_security_properties(ske,
1810                                                           params->flags,
1811                                                           params->version);
1812     if (!start_payload)
1813       return NULL;
1814   }
1815
1816   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1817   ske->start_payload = start_payload;
1818   ske->version = params->version;
1819   ske->running = TRUE;
1820
1821   /* Link to packet stream to get key exchange packets */
1822   ske->stream = stream;
1823   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1824                           SILC_PACKET_KEY_EXCHANGE,
1825                           SILC_PACKET_KEY_EXCHANGE_2,
1826                           SILC_PACKET_SUCCESS,
1827                           SILC_PACKET_FAILURE, -1);
1828
1829   /* Start SKE as initiator */
1830   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1831
1832   return &ske->op;
1833 }
1834
1835 /******************************** Responder *********************************/
1836
1837 /* Start protocol as responder.  Wait initiator's start payload */
1838
1839 SILC_FSM_STATE(silc_ske_st_responder_start)
1840 {
1841   SilcSKE ske = fsm_context;
1842
1843   SILC_LOG_DEBUG(("Start"));
1844
1845   if (ske->aborted) {
1846     /** Aborted */
1847     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1848     return SILC_FSM_CONTINUE;
1849   }
1850
1851   /* Add key exchange timeout */
1852   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1853                                  ske, ske->timeout, 0);
1854
1855   /** Wait for initiator */
1856   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1857   return SILC_FSM_WAIT;
1858 }
1859
1860 /* Decode initiator's start payload.  Select the security properties from
1861    the initiator's start payload and send our reply start payload back. */
1862
1863 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1864 {
1865   SilcSKE ske = fsm_context;
1866   SilcSKEStatus status;
1867   SilcSKEStartPayload remote_payload = NULL;
1868   SilcBuffer packet_buf = &ske->packet->buffer;
1869
1870   SILC_LOG_DEBUG(("Start"));
1871
1872   /* Decode the payload */
1873   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1874   if (status != SILC_SKE_STATUS_OK) {
1875     /** Error decoding Start Payload */
1876     silc_packet_free(ske->packet);
1877     ske->packet = NULL;
1878     ske->status = status;
1879     silc_fsm_next(fsm, silc_ske_st_responder_error);
1880     return SILC_FSM_CONTINUE;
1881   }
1882
1883   /* Take a copy of the payload buffer for future use. It is used to
1884      compute the HASH value. */
1885   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1886
1887   silc_packet_free(ske->packet);
1888   ske->packet = NULL;
1889
1890   /* Force the mutual authentication flag if we want to do it. */
1891   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1892     SILC_LOG_DEBUG(("Force mutual authentication"));
1893     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1894   }
1895
1896   /* Force PFS flag if we require it */
1897   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1898     SILC_LOG_DEBUG(("Force PFS"));
1899     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1900   }
1901
1902   /* Disable IV Included flag if requested */
1903   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1904       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1905     SILC_LOG_DEBUG(("We do not support IV Included flag"));
1906     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1907   }
1908
1909   /* Check and select security properties */
1910   status = silc_ske_select_security_properties(ske, remote_payload,
1911                                                &ske->prop);
1912   if (status != SILC_SKE_STATUS_OK) {
1913     /** Error selecting proposal */
1914     silc_ske_payload_start_free(remote_payload);
1915     ske->status = status;
1916     silc_fsm_next(fsm, silc_ske_st_responder_error);
1917     return SILC_FSM_CONTINUE;
1918   }
1919
1920   silc_ske_payload_start_free(remote_payload);
1921
1922   /* Encode our reply payload to send the selected security properties */
1923   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1924                                          &packet_buf);
1925   if (status != SILC_SKE_STATUS_OK)
1926     goto err;
1927
1928   /* Send the packet. */
1929   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1930                             silc_buffer_data(packet_buf),
1931                             silc_buffer_len(packet_buf)))
1932     goto err;
1933
1934   silc_buffer_free(packet_buf);
1935
1936   /** Waiting initiator's KE payload */
1937   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1938   return SILC_FSM_WAIT;
1939
1940  err:
1941   if (ske->prop->group)
1942     silc_ske_group_free(ske->prop->group);
1943   if (ske->prop->cipher)
1944     silc_cipher_free(ske->prop->cipher);
1945   if (ske->prop->hash)
1946     silc_hash_free(ske->prop->hash);
1947   if (ske->prop->hmac)
1948     silc_hmac_free(ske->prop->hmac);
1949   silc_free(ske->prop);
1950   ske->prop = NULL;
1951
1952   if (status == SILC_SKE_STATUS_OK)
1953     status = SILC_SKE_STATUS_ERROR;
1954
1955   /** Error */
1956   ske->status = status;
1957   silc_fsm_next(fsm, silc_ske_st_responder_error);
1958   return SILC_FSM_CONTINUE;
1959 }
1960
1961 /* Phase-2.  Decode initiator's KE payload */
1962
1963 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1964 {
1965   SilcSKE ske = fsm_context;
1966   SilcSKEStatus status;
1967   SilcSKEKEPayload recv_payload;
1968   SilcBuffer packet_buf = &ske->packet->buffer;
1969
1970   SILC_LOG_DEBUG(("Start"));
1971
1972   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1973     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1974     silc_ske_install_retransmission(ske);
1975     silc_packet_free(ske->packet);
1976     ske->packet = NULL;
1977     return SILC_FSM_WAIT;
1978   }
1979
1980   /* Decode Key Exchange Payload */
1981   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1982   if (status != SILC_SKE_STATUS_OK) {
1983     /** Error decoding KE payload */
1984     silc_packet_free(ske->packet);
1985     ske->packet = NULL;
1986     ske->status = status;
1987     silc_fsm_next(fsm, silc_ske_st_responder_error);
1988     return SILC_FSM_CONTINUE;
1989   }
1990
1991   ske->ke1_payload = recv_payload;
1992
1993   silc_packet_free(ske->packet);
1994   ske->packet = NULL;
1995
1996   /* Verify the received public key and verify the signature if we are
1997      doing mutual authentication. */
1998   if (ske->start_payload &&
1999       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2000
2001     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2002
2003     if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2004                                    ske->repository)) {
2005       /** Public key not provided */
2006       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2007                       "certificate), even though we require it"));
2008       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2009       silc_fsm_next(fsm, silc_ske_st_responder_error);
2010       return SILC_FSM_CONTINUE;
2011     }
2012
2013     /* Decode the remote's public key */
2014     if (recv_payload->pk_data &&
2015         !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2016                                     recv_payload->pk_data,
2017                                     recv_payload->pk_len,
2018                                     &ske->prop->public_key)) {
2019       /** Error decoding public key */
2020       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2021       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2022       silc_fsm_next(fsm, silc_ske_st_responder_error);
2023       return SILC_FSM_CONTINUE;
2024     }
2025
2026     if (ske->prop->public_key && (ske->callbacks->verify_key ||
2027                                   ske->repository)) {
2028       SILC_LOG_DEBUG(("Verifying public key"));
2029
2030       /** Waiting public key verification */
2031       silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2032
2033       /* If repository is provided, verify the key from there. */
2034       if (ske->repository) {
2035         SilcSKRFind find;
2036
2037         find = silc_skr_find_alloc();
2038         if (!find) {
2039           ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2040           silc_fsm_next(fsm, silc_ske_st_responder_error);
2041           return SILC_FSM_CONTINUE;
2042         }
2043         silc_skr_find_set_pkcs_type(find,
2044                                     silc_pkcs_get_type(ske->prop->public_key));
2045         silc_skr_find_set_public_key(find, ske->prop->public_key);
2046         silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2047
2048         /* Find key from repository */
2049         SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2050                                     silc_ske_skr_callback, ske));
2051       } else {
2052         /* Verify from application */
2053         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2054                                                  ske->callbacks->context,
2055                                                  silc_ske_pk_verified, NULL));
2056       }
2057       /* NOT REACHED */
2058     }
2059   }
2060
2061   /** Generate KE2 payload */
2062   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2063   return SILC_FSM_CONTINUE;
2064 }
2065
2066 /* Phase-4. Generate KE2 payload */
2067
2068 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2069 {
2070   SilcSKE ske = fsm_context;
2071   SilcSKEStatus status;
2072   SilcSKEKEPayload recv_payload, send_payload;
2073   SilcMPInt *x, *KEY;
2074
2075   if (ske->aborted) {
2076     /** Aborted */
2077     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2078     return SILC_FSM_CONTINUE;
2079   }
2080
2081   /* Check result of public key verification */
2082   if (ske->status != SILC_SKE_STATUS_OK) {
2083     /** Public key not verified */
2084     SILC_LOG_DEBUG(("Public key verification failed"));
2085     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2086     return SILC_FSM_CONTINUE;
2087   }
2088
2089   recv_payload = ske->ke1_payload;
2090
2091   /* The public key verification was performed only if the Mutual
2092      Authentication flag is set. */
2093   if (ske->start_payload &&
2094       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2095     unsigned char hash[SILC_HASH_MAXLEN];
2096     SilcUInt32 hash_len;
2097
2098     SILC_LOG_DEBUG(("Public key is authentic"));
2099
2100     /* Compute the hash value */
2101     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2102     if (status != SILC_SKE_STATUS_OK) {
2103       /** Error computing hash */
2104       ske->status = status;
2105       silc_fsm_next(fsm, silc_ske_st_responder_error);
2106       return SILC_FSM_CONTINUE;
2107     }
2108
2109     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2110
2111     /* Verify signature */
2112     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2113                           recv_payload->sign_len, hash, hash_len, NULL)) {
2114       /** Incorrect signature */
2115       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2116       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2117       silc_fsm_next(fsm, silc_ske_st_responder_error);
2118       return SILC_FSM_CONTINUE;
2119     }
2120
2121     SILC_LOG_DEBUG(("Signature is Ok"));
2122
2123     memset(hash, 'F', hash_len);
2124   }
2125
2126   /* Create the random number x, 1 < x < q. */
2127   x = silc_calloc(1, sizeof(*x));
2128   silc_mp_init(x);
2129   status =
2130     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2131                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2132                         x);
2133   if (status != SILC_SKE_STATUS_OK) {
2134     /** Error generating random number */
2135     silc_mp_uninit(x);
2136     silc_free(x);
2137     ske->status = status;
2138     silc_fsm_next(fsm, silc_ske_st_responder_error);
2139     return SILC_FSM_CONTINUE;
2140   }
2141
2142   /* Save the results for later processing */
2143   send_payload = silc_calloc(1, sizeof(*send_payload));
2144   ske->x = x;
2145   ske->ke2_payload = send_payload;
2146
2147   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2148
2149   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2150   silc_mp_init(&send_payload->x);
2151   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2152                   &ske->prop->group->group);
2153
2154   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2155
2156   /* Compute the shared secret key */
2157   KEY = silc_calloc(1, sizeof(*KEY));
2158   silc_mp_init(KEY);
2159   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2160                   &ske->prop->group->group);
2161   ske->KEY = KEY;
2162
2163   /** Send KE2 payload */
2164   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2165   return SILC_FSM_CONTINUE;
2166 }
2167
2168 /* Phase-5.  Send KE2 payload */
2169
2170 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2171 {
2172   SilcSKE ske = fsm_context;
2173   SilcSKEStatus status;
2174   SilcBuffer payload_buf;
2175   unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2176   SilcUInt32 hash_len, sign_len, pk_len;
2177
2178   SILC_LOG_DEBUG(("Start"));
2179
2180   if (ske->public_key && ske->private_key) {
2181     SILC_LOG_DEBUG(("Getting public key"));
2182
2183     /* Get the public key */
2184     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2185     if (!pk) {
2186       /** Error encoding public key */
2187       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2188       silc_fsm_next(fsm, silc_ske_st_responder_error);
2189       return SILC_FSM_CONTINUE;
2190     }
2191     ske->ke2_payload->pk_data = pk;
2192     ske->ke2_payload->pk_len = pk_len;
2193
2194     SILC_LOG_DEBUG(("Computing HASH value"));
2195
2196     /* Compute the hash value */
2197     memset(hash, 0, sizeof(hash));
2198     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2199     if (status != SILC_SKE_STATUS_OK) {
2200       /** Error computing hash */
2201       ske->status = status;
2202       silc_fsm_next(fsm, silc_ske_st_responder_error);
2203       return SILC_FSM_CONTINUE;
2204     }
2205
2206     ske->hash = silc_memdup(hash, hash_len);
2207     ske->hash_len = hash_len;
2208
2209     SILC_LOG_DEBUG(("Signing HASH value"));
2210
2211     /* Sign the hash value */
2212     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2213                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2214       /** Error computing signature */
2215       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2216       silc_fsm_next(fsm, silc_ske_st_responder_error);
2217       return SILC_FSM_CONTINUE;
2218     }
2219     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2220     ske->ke2_payload->sign_len = sign_len;
2221     memset(sign, 0, sizeof(sign));
2222   }
2223   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2224
2225   /* Encode the Key Exchange Payload */
2226   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2227                                       &payload_buf);
2228   if (status != SILC_SKE_STATUS_OK) {
2229     /** Error encoding KE payload */
2230     ske->status = status;
2231     silc_fsm_next(fsm, silc_ske_st_responder_error);
2232     return SILC_FSM_CONTINUE;
2233   }
2234
2235   /* Send the packet. */
2236   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2237                             payload_buf->data, silc_buffer_len(payload_buf))) {
2238     SILC_LOG_DEBUG(("Error sending packet"));
2239     ske->status = SILC_SKE_STATUS_ERROR;
2240     silc_fsm_next(fsm, silc_ske_st_responder_error);
2241     return SILC_FSM_CONTINUE;
2242   }
2243
2244   silc_buffer_free(payload_buf);
2245
2246   /** Waiting completion */
2247   silc_fsm_next(fsm, silc_ske_st_responder_end);
2248   return SILC_FSM_WAIT;
2249 }
2250
2251 /* Protocol completed */
2252
2253 SILC_FSM_STATE(silc_ske_st_responder_end)
2254 {
2255   SilcSKE ske = fsm_context;
2256   unsigned char tmp[4];
2257   SilcUInt32 hash_len, key_len, block_len;
2258
2259   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2260     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2261     silc_ske_install_retransmission(ske);
2262     silc_packet_free(ske->packet);
2263     ske->packet = NULL;
2264     return SILC_FSM_WAIT;
2265   }
2266   silc_packet_free(ske->packet);
2267   ske->packet = NULL;
2268
2269   /* Process key material */
2270   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2271   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2272   hash_len = silc_hash_len(ske->prop->hash);
2273   ske->keymat = silc_ske_process_key_material(ske, block_len,
2274                                               key_len, hash_len,
2275                                               &ske->rekey);
2276   if (!ske->keymat) {
2277     /** Error processing key material */
2278     ske->status = SILC_SKE_STATUS_ERROR;
2279     silc_fsm_next(fsm, silc_ske_st_responder_error);
2280     return SILC_FSM_CONTINUE;
2281   }
2282
2283   /* Send SUCCESS packet */
2284   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2285   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2286
2287   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2288   silc_schedule_task_del_by_context(ske->schedule, ske);
2289
2290   return SILC_FSM_FINISH;
2291 }
2292
2293 /* Aborted by application */
2294
2295 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2296 {
2297   SilcSKE ske = fsm_context;
2298   unsigned char tmp[4];
2299
2300   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2301
2302   /* Send FAILURE packet */
2303   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2304   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2305
2306   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2307   silc_schedule_task_del_by_context(ske->schedule, ske);
2308
2309   return SILC_FSM_FINISH;
2310 }
2311
2312 /* Failure received from remote */
2313
2314 SILC_FSM_STATE(silc_ske_st_responder_failure)
2315 {
2316   SilcSKE ske = fsm_context;
2317   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2318
2319   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2320
2321   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2322     SILC_GET32_MSB(error, ske->packet->buffer.data);
2323     ske->status = error;
2324     silc_packet_free(ske->packet);
2325     ske->packet = NULL;
2326   }
2327
2328   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2329   silc_schedule_task_del_by_context(ske->schedule, ske);
2330
2331   return SILC_FSM_FINISH;
2332 }
2333
2334 /* Error occurred */
2335
2336 SILC_FSM_STATE(silc_ske_st_responder_error)
2337 {
2338   SilcSKE ske = fsm_context;
2339   unsigned char tmp[4];
2340
2341   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2342                   ske->status, silc_ske_map_status(ske->status)));
2343
2344   /* Send FAILURE packet */
2345   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2346     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2347   SILC_PUT32_MSB(ske->status, tmp);
2348   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2349
2350   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2351   silc_schedule_task_del_by_context(ske->schedule, ske);
2352
2353   return SILC_FSM_FINISH;
2354 }
2355
2356 /* Starts the protocol as responder. */
2357
2358 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2359                                       SilcPacketStream stream,
2360                                       SilcSKEParams params)
2361 {
2362   SILC_LOG_DEBUG(("Start SKE as responder"));
2363
2364   if (!ske || !stream || !params || !params->version)
2365     return NULL;
2366
2367   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2368     return NULL;
2369
2370   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2371     return NULL;
2372
2373   ske->responder = TRUE;
2374   ske->flags = params->flags;
2375   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2376   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2377     ske->session_port = params->session_port;
2378   ske->version = strdup(params->version);
2379   if (!ske->version)
2380     return NULL;
2381   ske->running = TRUE;
2382
2383   /* Link to packet stream to get key exchange packets */
2384   ske->stream = stream;
2385   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2386                           SILC_PACKET_KEY_EXCHANGE,
2387                           SILC_PACKET_KEY_EXCHANGE_1,
2388                           SILC_PACKET_SUCCESS,
2389                           SILC_PACKET_FAILURE, -1);
2390
2391   /* Start SKE as responder */
2392   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2393
2394   return &ske->op;
2395 }
2396
2397 /***************************** Initiator Rekey ******************************/
2398
2399 /* Start rekey */
2400
2401 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2402 {
2403   SilcSKE ske = fsm_context;
2404   SilcStatus status;
2405
2406   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2407
2408   if (ske->aborted) {
2409     /** Aborted */
2410     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2411     return SILC_FSM_CONTINUE;
2412   }
2413
2414   /* Add rekey exchange timeout */
2415   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2416                                  ske, 30, 0);
2417
2418   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2419   if (!ske->prop) {
2420     /** No memory */
2421     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2422     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2423     return SILC_FSM_CONTINUE;
2424   }
2425
2426   /* Send REKEY packet to start rekey protocol */
2427   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2428     /** Error sending packet */
2429     SILC_LOG_DEBUG(("Error sending packet"));
2430     ske->status = SILC_SKE_STATUS_ERROR;
2431     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2432     return SILC_FSM_CONTINUE;
2433   }
2434
2435   /* If doing rekey without PFS, move directly to the end of the protocol. */
2436   if (!ske->rekey->pfs) {
2437     /** Rekey without PFS */
2438     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2439     return SILC_FSM_CONTINUE;
2440   }
2441
2442   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2443                                         &ske->prop->group);
2444   if (status != SILC_SKE_STATUS_OK) {
2445     /** Unknown group */
2446     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2447     return SILC_FSM_CONTINUE;
2448   }
2449
2450   /** Rekey with PFS */
2451   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2452   return SILC_FSM_CONTINUE;
2453 }
2454
2455 /* Sends REKEY_DONE packet to finish the protocol. */
2456
2457 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2458 {
2459   SilcSKE ske = fsm_context;
2460   SilcCipher send_key;
2461   SilcHmac hmac_send;
2462   SilcHash hash;
2463   SilcUInt32 key_len, block_len, hash_len, x_len;
2464   unsigned char *pfsbuf;
2465
2466   SILC_LOG_DEBUG(("Start"));
2467
2468   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2469   key_len = silc_cipher_get_key_len(send_key);
2470   block_len = silc_cipher_get_block_len(send_key);
2471
2472   if (!silc_hash_alloc(ske->rekey->hash, &hash)) {
2473     /** Cannot allocate hash */
2474     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2475     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2476     return SILC_FSM_CONTINUE;
2477   }
2478   hash_len = silc_hash_len(hash);
2479
2480   /* Process key material */
2481   if (ske->rekey->pfs) {
2482     /* PFS */
2483     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2484     if (pfsbuf) {
2485       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2486                                                        block_len, key_len,
2487                                                        hash_len, hash);
2488       memset(pfsbuf, 0, x_len);
2489       silc_free(pfsbuf);
2490     }
2491   } else {
2492     /* No PFS */
2493     ske->keymat =
2494       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2495                                          ske->rekey->enc_key_len / 8,
2496                                          block_len, key_len,
2497                                          hash_len, hash);
2498   }
2499
2500   if (!ske->keymat) {
2501     SILC_LOG_ERROR(("Error processing key material"));
2502     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2503     return SILC_FSM_CONTINUE;
2504   }
2505
2506   ske->prop->cipher = send_key;
2507   ske->prop->hmac = hmac_send;
2508   ske->prop->hash = hash;
2509
2510   /* Get sending keys */
2511   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2512                          &hmac_send, NULL, NULL)) {
2513     /** Cannot get keys */
2514     ske->status = SILC_SKE_STATUS_ERROR;
2515     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2516     return SILC_FSM_CONTINUE;
2517   }
2518
2519   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2520      packet sent after this call will be protected with the new keys. */
2521   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2522                             TRUE)) {
2523     /** Cannot set keys */
2524     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2525     ske->status = SILC_SKE_STATUS_ERROR;
2526     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2527     return SILC_FSM_CONTINUE;
2528   }
2529
2530   /** Wait for REKEY_DONE */
2531   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2532   return SILC_FSM_WAIT;
2533 }
2534
2535 /* Rekey protocol end */
2536
2537 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2538 {
2539   SilcSKE ske = fsm_context;
2540   SilcCipher receive_key;
2541   SilcHmac hmac_receive;
2542   SilcSKERekeyMaterial rekey;
2543
2544   SILC_LOG_DEBUG(("Start"));
2545
2546   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2547     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2548     silc_packet_free(ske->packet);
2549     ske->packet = NULL;
2550     return SILC_FSM_WAIT;
2551   }
2552
2553   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2554   ske->prop->cipher = receive_key;
2555   ske->prop->hmac = hmac_receive;
2556
2557   /* Get receiving keys */
2558   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2559                          NULL, &hmac_receive, NULL)) {
2560     /** Cannot get keys */
2561     ske->status = SILC_SKE_STATUS_ERROR;
2562     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2563     return SILC_FSM_CONTINUE;
2564   }
2565
2566   /* Set new receiving keys into use.  All packets received after this will
2567      be decrypted with the new keys. */
2568   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2569                             hmac_receive, FALSE)) {
2570     /** Cannot set keys */
2571     SILC_LOG_DEBUG(("Cannot set new keys"));
2572     ske->status = SILC_SKE_STATUS_ERROR;
2573     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2574     return SILC_FSM_CONTINUE;
2575   }
2576
2577   SILC_LOG_DEBUG(("Rekey completed successfully"));
2578
2579   /* Generate new rekey material */
2580   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2581   if (!rekey) {
2582     /** No memory */
2583     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2584     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2585     return SILC_FSM_CONTINUE;
2586   }
2587   rekey->pfs = ske->rekey->pfs;
2588   ske->rekey = rekey;
2589
2590   ske->prop->cipher = NULL;
2591   ske->prop->hmac = NULL;
2592   silc_packet_free(ske->packet);
2593   ske->packet = NULL;
2594   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2595   silc_schedule_task_del_by_context(ske->schedule, ske);
2596
2597   return SILC_FSM_FINISH;
2598 }
2599
2600 /* Starts rekey protocol as initiator */
2601
2602 SilcAsyncOperation
2603 silc_ske_rekey_initiator(SilcSKE ske,
2604                          SilcPacketStream stream,
2605                          SilcSKERekeyMaterial rekey)
2606 {
2607   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2608
2609   if (!ske || !stream || !rekey)
2610     return NULL;
2611
2612   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2613     return NULL;
2614
2615   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2616     return NULL;
2617
2618   ske->rekey = rekey;
2619   ske->responder = FALSE;
2620   ske->running = TRUE;
2621   ske->rekeying = TRUE;
2622
2623   /* Link to packet stream to get key exchange packets */
2624   ske->stream = stream;
2625   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2626                           SILC_PACKET_REKEY,
2627                           SILC_PACKET_REKEY_DONE,
2628                           SILC_PACKET_KEY_EXCHANGE_2,
2629                           SILC_PACKET_SUCCESS,
2630                           SILC_PACKET_FAILURE, -1);
2631
2632   /* Start SKE rekey as initiator */
2633   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2634
2635   return &ske->op;
2636 }
2637
2638 /***************************** Responder Rekey ******************************/
2639
2640 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2641
2642 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2643 {
2644   return SILC_FSM_FINISH;
2645 }
2646
2647 /* Starts rekey protocol as responder */
2648
2649 SilcAsyncOperation
2650 silc_ske_rekey_responder(SilcSKE ske,
2651                          SilcPacketStream stream,
2652                          SilcSKERekeyMaterial rekey)
2653 {
2654   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2655
2656   if (!ske || !stream || !rekey)
2657     return NULL;
2658
2659   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2660     return NULL;
2661
2662   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2663     return NULL;
2664
2665   ske->rekey = rekey;
2666   ske->responder = TRUE;
2667   ske->running = TRUE;
2668   ske->rekeying = TRUE;
2669
2670   /* Link to packet stream to get key exchange packets */
2671   ske->stream = stream;
2672   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2673                           SILC_PACKET_REKEY,
2674                           SILC_PACKET_REKEY_DONE,
2675                           SILC_PACKET_KEY_EXCHANGE_1,
2676                           SILC_PACKET_SUCCESS,
2677                           SILC_PACKET_FAILURE, -1);
2678
2679   /* Start SKE rekey as responder */
2680   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2681
2682   return &ske->op;
2683 }
2684
2685 /* Processes the provided key material `data' as the SILC protocol
2686    specification defines. */
2687
2688 SilcSKEKeyMaterial
2689 silc_ske_process_key_material_data(unsigned char *data,
2690                                    SilcUInt32 data_len,
2691                                    SilcUInt32 req_iv_len,
2692                                    SilcUInt32 req_enc_key_len,
2693                                    SilcUInt32 req_hmac_key_len,
2694                                    SilcHash hash)
2695 {
2696   SilcBuffer buf;
2697   unsigned char hashd[SILC_HASH_MAXLEN];
2698   SilcUInt32 hash_len = req_hmac_key_len;
2699   SilcUInt32 enc_key_len = req_enc_key_len / 8;
2700   SilcSKEKeyMaterial key;
2701
2702   SILC_LOG_DEBUG(("Start"));
2703
2704   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2705     return NULL;
2706
2707   key = silc_calloc(1, sizeof(*key));
2708   if (!key)
2709     return NULL;
2710
2711   buf = silc_buffer_alloc_size(1 + data_len);
2712   if (!buf)
2713     return NULL;
2714   silc_buffer_format(buf,
2715                      SILC_STR_UI_CHAR(0),
2716                      SILC_STR_UI_XNSTRING(data, data_len),
2717                      SILC_STR_END);
2718
2719   /* Take IVs */
2720   memset(hashd, 0, sizeof(hashd));
2721   buf->data[0] = 0;
2722   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2723   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2724   memcpy(key->send_iv, hashd, req_iv_len);
2725   memset(hashd, 0, sizeof(hashd));
2726   buf->data[0] = 1;
2727   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2728   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2729   memcpy(key->receive_iv, hashd, req_iv_len);
2730   key->iv_len = req_iv_len;
2731
2732   /* Take the encryption keys. If requested key size is more than
2733      the size of hash length we will distribute more key material
2734      as protocol defines. */
2735   buf->data[0] = 2;
2736   if (enc_key_len > hash_len) {
2737     SilcBuffer dist;
2738     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2739         k3[SILC_HASH_MAXLEN];
2740     unsigned char *dtmp;
2741
2742     /* XXX */
2743     if (enc_key_len > (3 * hash_len))
2744       return NULL;
2745
2746     /* Take first round */
2747     memset(k1, 0, sizeof(k1));
2748     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2749
2750     /* Take second round */
2751     dist = silc_buffer_alloc_size(data_len + hash_len);
2752     if (!dist)
2753       return NULL;
2754     silc_buffer_format(dist,
2755                        SILC_STR_UI_XNSTRING(data, data_len),
2756                        SILC_STR_UI_XNSTRING(k1, hash_len),
2757                        SILC_STR_END);
2758     memset(k2, 0, sizeof(k2));
2759     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2760
2761     /* Take third round */
2762     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2763     silc_buffer_pull_tail(dist, hash_len);
2764     silc_buffer_pull(dist, data_len + hash_len);
2765     silc_buffer_format(dist,
2766                        SILC_STR_UI_XNSTRING(k2, hash_len),
2767                        SILC_STR_END);
2768     silc_buffer_push(dist, data_len + hash_len);
2769     memset(k3, 0, sizeof(k3));
2770     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2771
2772     /* Then, save the keys */
2773     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2774     memcpy(dtmp, k1, hash_len);
2775     memcpy(dtmp + hash_len, k2, hash_len);
2776     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2777
2778     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2779     memcpy(key->send_enc_key, dtmp, enc_key_len);
2780     key->enc_key_len = req_enc_key_len;
2781
2782     memset(dtmp, 0, (3 * hash_len));
2783     memset(k1, 0, sizeof(k1));
2784     memset(k2, 0, sizeof(k2));
2785     memset(k3, 0, sizeof(k3));
2786     silc_free(dtmp);
2787     silc_buffer_clear(dist);
2788     silc_buffer_free(dist);
2789   } else {
2790     /* Take normal hash as key */
2791     memset(hashd, 0, sizeof(hashd));
2792     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2793     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2794     memcpy(key->send_enc_key, hashd, enc_key_len);
2795     key->enc_key_len = req_enc_key_len;
2796   }
2797
2798   buf->data[0] = 3;
2799   if (enc_key_len > hash_len) {
2800     SilcBuffer dist;
2801     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2802         k3[SILC_HASH_MAXLEN];
2803     unsigned char *dtmp;
2804
2805     /* XXX */
2806     if (enc_key_len > (3 * hash_len))
2807       return NULL;
2808
2809     /* Take first round */
2810     memset(k1, 0, sizeof(k1));
2811     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2812
2813     /* Take second round */
2814     dist = silc_buffer_alloc_size(data_len + hash_len);
2815     if (!dist)
2816       return NULL;
2817     silc_buffer_format(dist,
2818                        SILC_STR_UI_XNSTRING(data, data_len),
2819                        SILC_STR_UI_XNSTRING(k1, hash_len),
2820                        SILC_STR_END);
2821     memset(k2, 0, sizeof(k2));
2822     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2823
2824     /* Take third round */
2825     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2826     silc_buffer_pull_tail(dist, hash_len);
2827     silc_buffer_pull(dist, data_len + hash_len);
2828     silc_buffer_format(dist,
2829                        SILC_STR_UI_XNSTRING(k2, hash_len),
2830                        SILC_STR_END);
2831     silc_buffer_push(dist, data_len + hash_len);
2832     memset(k3, 0, sizeof(k3));
2833     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2834
2835     /* Then, save the keys */
2836     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2837     memcpy(dtmp, k1, hash_len);
2838     memcpy(dtmp + hash_len, k2, hash_len);
2839     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2840
2841     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2842     memcpy(key->receive_enc_key, dtmp, enc_key_len);
2843     key->enc_key_len = req_enc_key_len;
2844
2845     memset(dtmp, 0, (3 * hash_len));
2846     memset(k1, 0, sizeof(k1));
2847     memset(k2, 0, sizeof(k2));
2848     memset(k3, 0, sizeof(k3));
2849     silc_free(dtmp);
2850     silc_buffer_clear(dist);
2851     silc_buffer_free(dist);
2852   } else {
2853     /* Take normal hash as key */
2854     memset(hashd, 0, sizeof(hashd));
2855     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2856     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2857     memcpy(key->receive_enc_key, hashd, enc_key_len);
2858     key->enc_key_len = req_enc_key_len;
2859   }
2860
2861   /* Take HMAC keys */
2862   memset(hashd, 0, sizeof(hashd));
2863   buf->data[0] = 4;
2864   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2865   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2866   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2867   memset(hashd, 0, sizeof(hashd));
2868   buf->data[0] = 5;
2869   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2870   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2871   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2872   key->hmac_key_len = req_hmac_key_len;
2873   memset(hashd, 0, sizeof(hashd));
2874
2875   silc_buffer_clear(buf);
2876   silc_buffer_free(buf);
2877
2878   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
2879
2880   return key;
2881 }
2882
2883 /* Processes negotiated key material as protocol specifies. This returns
2884    the actual keys to be used in the SILC. */
2885
2886 SilcSKEKeyMaterial
2887 silc_ske_process_key_material(SilcSKE ske,
2888                               SilcUInt32 req_iv_len,
2889                               SilcUInt32 req_enc_key_len,
2890                               SilcUInt32 req_hmac_key_len,
2891                               SilcSKERekeyMaterial *rekey)
2892 {
2893   SilcBuffer buf;
2894   unsigned char *tmpbuf;
2895   SilcUInt32 klen;
2896   SilcSKEKeyMaterial key;
2897
2898   /* Encode KEY to binary data */
2899   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2900
2901   buf = silc_buffer_alloc_size(klen + ske->hash_len);
2902   if (!buf)
2903     return NULL;
2904   silc_buffer_format(buf,
2905                      SILC_STR_UI_XNSTRING(tmpbuf, klen),
2906                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2907                      SILC_STR_END);
2908
2909   /* Process the key material */
2910   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2911                                            req_iv_len, req_enc_key_len,
2912                                            req_hmac_key_len,
2913                                            ske->prop->hash);
2914
2915   memset(tmpbuf, 0, klen);
2916   silc_free(tmpbuf);
2917   silc_buffer_clear(buf);
2918   silc_buffer_free(buf);
2919
2920   if (rekey) {
2921     *rekey = silc_ske_make_rekey_material(ske, key);
2922     if (!(*rekey))
2923       return NULL;
2924   }
2925
2926   return key;
2927 }
2928
2929 /* Free key material structure */
2930
2931 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2932 {
2933   if (!key)
2934     return;
2935
2936   if (key->send_iv)
2937     silc_free(key->send_iv);
2938   if (key->receive_iv)
2939     silc_free(key->receive_iv);
2940   if (key->send_enc_key) {
2941     memset(key->send_enc_key, 0, key->enc_key_len / 8);
2942     silc_free(key->send_enc_key);
2943   }
2944   if (key->receive_enc_key) {
2945     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2946     silc_free(key->receive_enc_key);
2947   }
2948   if (key->send_hmac_key) {
2949     memset(key->send_hmac_key, 0, key->hmac_key_len);
2950     silc_free(key->send_hmac_key);
2951   }
2952   if (key->receive_hmac_key) {
2953     memset(key->receive_hmac_key, 0, key->hmac_key_len);
2954     silc_free(key->receive_hmac_key);
2955   }
2956   silc_free(key);
2957 }
2958
2959 /* Free rekey material */
2960
2961 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
2962 {
2963   if (!rekey)
2964     return;
2965   if (rekey->send_enc_key) {
2966     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
2967     silc_free(rekey->send_enc_key);
2968   }
2969   silc_free(rekey->hash);
2970   silc_free(rekey);
2971 }
2972
2973 /* Set keys into use */
2974
2975 SilcBool silc_ske_set_keys(SilcSKE ske,
2976                            SilcSKEKeyMaterial keymat,
2977                            SilcSKESecurityProperties prop,
2978                            SilcCipher *ret_send_key,
2979                            SilcCipher *ret_receive_key,
2980                            SilcHmac *ret_hmac_send,
2981                            SilcHmac *ret_hmac_receive,
2982                            SilcHash *ret_hash)
2983 {
2984   unsigned char iv[32];
2985
2986   /* Allocate ciphers to be used in the communication */
2987   if (ret_send_key) {
2988     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2989                            ret_send_key))
2990       return FALSE;
2991   }
2992   if (ret_receive_key) {
2993     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2994                            ret_receive_key))
2995       return FALSE;
2996   }
2997
2998   /* Allocate HMACs */
2999   if (ret_hmac_send) {
3000     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3001                          ret_hmac_send))
3002       return FALSE;
3003   }
3004   if (ret_hmac_receive) {
3005     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3006                          ret_hmac_receive))
3007       return FALSE;
3008   }
3009
3010   /* Set key material */
3011   memset(iv, 0, sizeof(iv));
3012   if (ske->responder) {
3013     if (ret_send_key) {
3014       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3015                           keymat->enc_key_len, TRUE);
3016
3017       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3018         memcpy(iv, ske->hash, 4);
3019         memcpy(iv + 4, keymat->receive_iv, 4);
3020         silc_cipher_set_iv(*ret_send_key, iv);
3021       } else {
3022         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3023       }
3024     }
3025     if (ret_receive_key) {
3026       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3027                           keymat->enc_key_len, FALSE);
3028
3029       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3030         memcpy(iv, ske->hash, 4);
3031         memcpy(iv + 4, keymat->send_iv, 4);
3032         silc_cipher_set_iv(*ret_receive_key, iv);
3033       } else {
3034         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3035       }
3036     }
3037     if (ret_hmac_send)
3038       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3039                         keymat->hmac_key_len);
3040     if (ret_hmac_receive)
3041       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3042                         keymat->hmac_key_len);
3043   } else {
3044     if (ret_send_key) {
3045       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3046                           keymat->enc_key_len, TRUE);
3047
3048       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3049         memcpy(iv, ske->hash, 4);
3050         memcpy(iv + 4, keymat->send_iv, 4);
3051         silc_cipher_set_iv(*ret_send_key, iv);
3052       } else {
3053         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3054       }
3055     }
3056     if (ret_receive_key) {
3057       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3058                           keymat->enc_key_len, FALSE);
3059
3060       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3061         memcpy(iv, ske->hash, 4);
3062         memcpy(iv + 4, keymat->receive_iv, 4);
3063         silc_cipher_set_iv(*ret_receive_key, iv);
3064       } else {
3065         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3066       }
3067     }
3068     if (ret_hmac_send)
3069       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3070                         keymat->hmac_key_len);
3071     if (ret_hmac_receive)
3072       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3073                         keymat->hmac_key_len);
3074   }
3075
3076   /* Allocate hash */
3077   if (ret_hash) {
3078     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3079       return FALSE;
3080   }
3081
3082   return TRUE;
3083 }
3084
3085 const char *silc_ske_status_string[] =
3086 {
3087   /* Official */
3088   "Ok",
3089   "Unkown error occurred",
3090   "Bad payload in packet",
3091   "Unsupported group",
3092   "Unsupported cipher",
3093   "Unsupported PKCS",
3094   "Unsupported hash function",
3095   "Unsupported HMAC",
3096   "Unsupported public key (or certificate)",
3097   "Incorrect signature",
3098   "Bad or unsupported version",
3099   "Invalid cookie",
3100
3101   /* Other errors */
3102   "Remote did not provide public key",
3103   "Bad reserved field in packet",
3104   "Bad payload length in packet",
3105   "Error computing signature",
3106   "System out of memory",
3107   "Key exchange timeout",
3108
3109   NULL
3110 };
3111
3112 /* Maps status to readable string and returns the string. If string is not
3113    found and empty character string ("") is returned. */
3114
3115 const char *silc_ske_map_status(SilcSKEStatus status)
3116 {
3117   int i;
3118
3119   for (i = 0; silc_ske_status_string[i]; i++)
3120     if (status == i)
3121       return silc_ske_status_string[i];
3122
3123   return "";
3124 }
3125
3126 /* Parses remote host's version string. */
3127
3128 SilcBool silc_ske_parse_version(SilcSKE ske,
3129                                 SilcUInt32 *protocol_version,
3130                                 char **protocol_version_string,
3131                                 SilcUInt32 *software_version,
3132                                 char **software_version_string,
3133                                 char **vendor_version)
3134 {
3135   return silc_parse_version_string(ske->remote_version,
3136                                    protocol_version,
3137                                    protocol_version_string,
3138                                    software_version,
3139                                    software_version_string,
3140                                    vendor_version);
3141 }
3142
3143 /* Get security properties */
3144
3145 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3146 {
3147   return ske->prop;
3148 }
3149
3150 /* Get key material */
3151
3152 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3153 {
3154   return ske->keymat;
3155 }