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