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