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