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