Fix reference counting for key exchange handling.
[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->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     silc_ske_free(ske);
977 }
978
979 /* Key exchange timeout task callback */
980
981 SILC_TASK_CALLBACK(silc_ske_timeout)
982 {
983   SilcSKE ske = context;
984
985   SILC_LOG_DEBUG(("Timeout"));
986
987   ske->packet = NULL;
988   ske->status = SILC_SKE_STATUS_TIMEOUT;
989   if (ske->responder)
990     silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
991   else
992     silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
993
994   silc_fsm_continue_sync(&ske->fsm);
995 }
996
997 /******************************* Protocol API *******************************/
998
999 /* Allocates new SKE object. */
1000
1001 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
1002                        SilcSKR repository, SilcPublicKey public_key,
1003                        SilcPrivateKey private_key, void *context)
1004 {
1005   SilcSKE ske;
1006
1007   SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
1008
1009   if (!rng || !schedule)
1010     return NULL;
1011
1012   if (!public_key) {
1013     SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
1014     return NULL;
1015   }
1016
1017   ske = silc_calloc(1, sizeof(*ske));
1018   if (!ske)
1019     return NULL;
1020   ske->status = SILC_SKE_STATUS_OK;
1021   ske->rng = rng;
1022   ske->repository = repository;
1023   ske->user_data = context;
1024   ske->schedule = schedule;
1025   ske->public_key = public_key;
1026   ske->private_key = private_key;
1027   ske->retry_timer = SILC_SKE_RETRY_MIN;
1028   ske->refcnt = 1;
1029
1030   return ske;
1031 }
1032
1033 /* Free's SKE object. */
1034
1035 void silc_ske_free(SilcSKE ske)
1036 {
1037   if (!ske)
1038     return;
1039
1040   SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt));
1041
1042     if (ske->aborted) {
1043       /* If already aborted, destroy the session immediately */
1044       ske->packet = NULL;
1045       ske->status = SILC_SKE_STATUS_ERROR;
1046       if (ske->responder)
1047         silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
1048       else
1049         silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
1050       silc_fsm_continue_sync(&ske->fsm);
1051     }
1052
1053   ske->refcnt--;
1054   if (ske->refcnt > 0)
1055     return;
1056
1057   /* Free start payload */
1058   if (ske->start_payload)
1059     silc_ske_payload_start_free(ske->start_payload);
1060
1061   /* Free KE payload */
1062   if (ske->ke1_payload)
1063     silc_ske_payload_ke_free(ske->ke1_payload);
1064   if (ske->ke2_payload)
1065     silc_ske_payload_ke_free(ske->ke2_payload);
1066   silc_free(ske->remote_version);
1067
1068   /* Free rest */
1069   if (ske->prop) {
1070     if (ske->prop->group)
1071       silc_ske_group_free(ske->prop->group);
1072     if (ske->prop->cipher)
1073       silc_cipher_free(ske->prop->cipher);
1074     if (ske->prop->hash)
1075       silc_hash_free(ske->prop->hash);
1076     if (ske->prop->hmac)
1077       silc_hmac_free(ske->prop->hmac);
1078     if (ske->prop->public_key)
1079       silc_pkcs_public_key_free(ske->prop->public_key);
1080     silc_free(ske->prop);
1081   }
1082   if (ske->keymat)
1083     silc_ske_free_key_material(ske->keymat);
1084   if (ske->start_payload_copy)
1085     silc_buffer_free(ske->start_payload_copy);
1086   if (ske->x) {
1087     silc_mp_uninit(ske->x);
1088     silc_free(ske->x);
1089   }
1090   if (ske->KEY) {
1091     silc_mp_uninit(ske->KEY);
1092     silc_free(ske->KEY);
1093   }
1094   silc_free(ske->retrans.data);
1095   silc_free(ske->hash);
1096   silc_free(ske->callbacks);
1097
1098   memset(ske, 0xdd, sizeof(*ske));
1099   silc_free(ske);
1100 }
1101
1102 /* Return user context */
1103
1104 void *silc_ske_get_context(SilcSKE ske)
1105 {
1106   return ske->user_data;
1107 }
1108
1109 /* Sets protocol callbacks */
1110
1111 void silc_ske_set_callbacks(SilcSKE ske,
1112                             SilcSKEVerifyCb verify_key,
1113                             SilcSKECompletionCb completed,
1114                             void *context)
1115 {
1116   if (ske->callbacks)
1117     silc_free(ske->callbacks);
1118   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
1119   if (!ske->callbacks)
1120     return;
1121   ske->callbacks->verify_key = verify_key;
1122   ske->callbacks->completed = completed;
1123   ske->callbacks->context = context;
1124 }
1125
1126
1127 /******************************** Initiator *********************************/
1128
1129 /* Start protocol.  Send our proposal */
1130
1131 SILC_FSM_STATE(silc_ske_st_initiator_start)
1132 {
1133   SilcSKE ske = fsm_context;
1134   SilcBuffer payload_buf;
1135   SilcStatus status;
1136
1137   SILC_LOG_DEBUG(("Start"));
1138
1139   if (ske->aborted) {
1140     /** Aborted */
1141     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1142     return SILC_FSM_CONTINUE;
1143   }
1144
1145   /* Encode the payload */
1146   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1147                                          &payload_buf);
1148   if (status != SILC_SKE_STATUS_OK) {
1149     /** Error encoding Start Payload */
1150     ske->status = status;
1151     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1152     return SILC_FSM_CONTINUE;
1153   }
1154
1155   /* Save the the payload buffer for future use. It is later used to
1156      compute the HASH value. */
1157   ske->start_payload_copy = payload_buf;
1158
1159   /* Send the packet. */
1160   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1161                             silc_buffer_data(payload_buf),
1162                             silc_buffer_len(payload_buf))) {
1163     /** Error sending packet */
1164     SILC_LOG_DEBUG(("Error sending packet"));
1165     ske->status = SILC_SKE_STATUS_ERROR;
1166     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1167     return SILC_FSM_CONTINUE;
1168   }
1169
1170   /* Add key exchange timeout */
1171   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1172                                  ske, ske->timeout, 0);
1173
1174   /** Wait for responder proposal */
1175   SILC_LOG_DEBUG(("Waiting for responder proposal"));
1176   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1177   return SILC_FSM_WAIT;
1178 }
1179
1180 /* Phase-1.  Receives responder's proposal */
1181
1182 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1183 {
1184   SilcSKE ske = fsm_context;
1185   SilcSKEStatus status;
1186   SilcSKEStartPayload payload;
1187   SilcSKESecurityProperties prop;
1188   SilcSKEDiffieHellmanGroup group = NULL;
1189   SilcBuffer packet_buf = &ske->packet->buffer;
1190   SilcUInt16 remote_port = 0;
1191   SilcID id;
1192   int coff = 0;
1193
1194   SILC_LOG_DEBUG(("Start"));
1195
1196   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1197     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1198     silc_ske_install_retransmission(ske);
1199     silc_packet_free(ske->packet);
1200     ske->packet = NULL;
1201     return SILC_FSM_WAIT;
1202   }
1203
1204   /* Decode the payload */
1205   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1206   if (status != SILC_SKE_STATUS_OK) {
1207     /** Error decoding Start Payload */
1208     silc_packet_free(ske->packet);
1209     ske->packet = NULL;
1210     ske->status = status;
1211     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1212     return SILC_FSM_CONTINUE;
1213   }
1214
1215   /* Get remote ID and set it to stream */
1216   if (ske->packet->src_id_len) {
1217     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1218                    ske->packet->src_id_type,
1219                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1220                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1221                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1222                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1223     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1224                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1225                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1226   }
1227
1228   silc_packet_free(ske->packet);
1229   ske->packet = NULL;
1230
1231   /* Check that the cookie is returned unmodified.  In case IV included
1232      flag and session port has been set, the first two bytes of cookie
1233      are the session port and we ignore them in this check. */
1234   if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1235     /* Take remote port */
1236     SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1237     coff = 2;
1238   }
1239   if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1240              SILC_SKE_COOKIE_LEN - coff)) {
1241     /** Invalid cookie */
1242     SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1243     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1244     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1245     return SILC_FSM_CONTINUE;
1246   }
1247
1248   /* Check version string */
1249   ske->remote_version = silc_memdup(payload->version, payload->version_len);
1250   status = silc_ske_check_version(ske);
1251   if (status != SILC_SKE_STATUS_OK) {
1252     /** Version mismatch */
1253     ske->status = status;
1254     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1255     return SILC_FSM_CONTINUE;
1256   }
1257
1258   /* Free our KE Start Payload context, we don't need it anymore. */
1259   silc_ske_payload_start_free(ske->start_payload);
1260   ske->start_payload = NULL;
1261
1262   /* Take the selected security properties into use while doing
1263      the key exchange.  This is used only while doing the key
1264      exchange. */
1265   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1266   if (!ske->prop)
1267     goto err;
1268   prop->flags = payload->flags;
1269   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1270   if (status != SILC_SKE_STATUS_OK)
1271     goto err;
1272
1273   prop->group = group;
1274   prop->remote_port = remote_port;
1275
1276   if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1277     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1278     goto err;
1279   }
1280   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1281     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1282     goto err;
1283   }
1284   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1285     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1286     goto err;
1287   }
1288   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1289     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1290     goto err;
1291   }
1292
1293   /* Save remote's KE Start Payload */
1294   ske->start_payload = payload;
1295
1296   /** Send KE Payload */
1297   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1298   return SILC_FSM_CONTINUE;
1299
1300  err:
1301   if (payload)
1302     silc_ske_payload_start_free(payload);
1303   if (group)
1304     silc_ske_group_free(group);
1305   if (prop->cipher)
1306     silc_cipher_free(prop->cipher);
1307   if (prop->hash)
1308     silc_hash_free(prop->hash);
1309   if (prop->hmac)
1310     silc_hmac_free(prop->hmac);
1311   silc_free(prop);
1312   ske->prop = NULL;
1313
1314   if (status == SILC_SKE_STATUS_OK)
1315     status = SILC_SKE_STATUS_ERROR;
1316
1317   /** Error */
1318   ske->status = status;
1319   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1320   return SILC_FSM_CONTINUE;
1321 }
1322
1323 /* Phase-2.  Send KE payload */
1324
1325 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1326 {
1327   SilcSKE ske = fsm_context;
1328   SilcSKEStatus status;
1329   SilcBuffer payload_buf;
1330   SilcMPInt *x;
1331   SilcSKEKEPayload payload;
1332   SilcUInt32 pk_len;
1333
1334   SILC_LOG_DEBUG(("Start"));
1335
1336   /* Create the random number x, 1 < x < q. */
1337   x = silc_calloc(1, sizeof(*x));
1338   if (!x){
1339     /** Out of memory */
1340     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1341     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1342     return SILC_FSM_CONTINUE;
1343   }
1344   silc_mp_init(x);
1345   status =
1346     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1347                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1348                         x);
1349   if (status != SILC_SKE_STATUS_OK) {
1350     /** Error generating random number */
1351     silc_mp_uninit(x);
1352     silc_free(x);
1353     ske->status = status;
1354     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1355     return SILC_FSM_CONTINUE;
1356   }
1357
1358   /* Encode the result to Key Exchange Payload. */
1359
1360   payload = silc_calloc(1, sizeof(*payload));
1361   if (!payload) {
1362     /** Out of memory */
1363     silc_mp_uninit(x);
1364     silc_free(x);
1365     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1366     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1367     return SILC_FSM_CONTINUE;
1368   }
1369   ske->ke1_payload = payload;
1370
1371   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1372
1373   /* Do the Diffie Hellman computation, e = g ^ x mod p */
1374   silc_mp_init(&payload->x);
1375   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1376                   &ske->prop->group->group);
1377
1378   /* Get public key */
1379   payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1380   if (!payload->pk_data) {
1381     /** Error encoding public key */
1382     silc_mp_uninit(x);
1383     silc_free(x);
1384     silc_mp_uninit(&payload->x);
1385     silc_free(payload);
1386     ske->ke1_payload = NULL;
1387     ske->status = SILC_SKE_STATUS_ERROR;
1388     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1389     return SILC_FSM_CONTINUE;
1390   }
1391   payload->pk_len = pk_len;
1392   payload->pk_type = silc_pkcs_get_type(ske->public_key);
1393
1394   /* Compute signature data if we are doing mutual authentication */
1395   if (ske->private_key && ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1396     unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1397     SilcUInt32 hash_len, sign_len;
1398
1399     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1400     SILC_LOG_DEBUG(("Computing HASH_i value"));
1401
1402     /* Compute the hash value */
1403     memset(hash, 0, sizeof(hash));
1404     silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1405
1406     SILC_LOG_DEBUG(("Signing HASH_i value"));
1407
1408     /* Sign the hash value */
1409     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1410                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
1411       /** Error computing signature */
1412       silc_mp_uninit(x);
1413       silc_free(x);
1414       silc_mp_uninit(&payload->x);
1415       silc_free(payload->pk_data);
1416       silc_free(payload);
1417       ske->ke1_payload = NULL;
1418       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1419       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1420       return SILC_FSM_CONTINUE;
1421     }
1422     payload->sign_data = silc_memdup(sign, sign_len);
1423     if (payload->sign_data)
1424       payload->sign_len = sign_len;
1425     memset(sign, 0, sizeof(sign));
1426   }
1427
1428   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1429   if (status != SILC_SKE_STATUS_OK) {
1430     /** Error encoding KE payload */
1431     silc_mp_uninit(x);
1432     silc_free(x);
1433     silc_mp_uninit(&payload->x);
1434     silc_free(payload->pk_data);
1435     silc_free(payload->sign_data);
1436     silc_free(payload);
1437     ske->ke1_payload = NULL;
1438     ske->status = status;
1439     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1440     return SILC_FSM_CONTINUE;
1441   }
1442
1443   ske->x = x;
1444
1445   /* Check for backwards compatibility */
1446
1447   /* Send the packet. */
1448   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1449                             silc_buffer_data(payload_buf),
1450                             silc_buffer_len(payload_buf))) {
1451     /** Error sending packet */
1452     SILC_LOG_DEBUG(("Error sending packet"));
1453     ske->status = SILC_SKE_STATUS_ERROR;
1454     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1455     return SILC_FSM_CONTINUE;
1456   }
1457
1458   silc_buffer_free(payload_buf);
1459
1460   /** Waiting responder's KE payload */
1461   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1462   return SILC_FSM_WAIT;
1463 }
1464
1465 /* Phase-3.  Process responder's KE payload */
1466
1467 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1468 {
1469   SilcSKE ske = fsm_context;
1470   SilcSKEStatus status;
1471   SilcSKEKEPayload payload;
1472   SilcMPInt *KEY;
1473   SilcBuffer packet_buf = &ske->packet->buffer;
1474
1475   SILC_LOG_DEBUG(("Start"));
1476
1477   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1478     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1479     silc_ske_install_retransmission(ske);
1480     silc_packet_free(ske->packet);
1481     ske->packet = NULL;
1482     return SILC_FSM_WAIT;
1483   }
1484
1485   /* Decode the payload */
1486   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1487   if (status != SILC_SKE_STATUS_OK) {
1488     /** Error decoding KE payload */
1489     silc_packet_free(ske->packet);
1490     ske->packet = NULL;
1491     ske->status = status;
1492     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1493     return SILC_FSM_CONTINUE;
1494   }
1495   silc_packet_free(ske->packet);
1496   ske->packet = NULL;
1497   ske->ke2_payload = payload;
1498
1499   if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1500     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1501                     "even though we require it"));
1502     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1503     goto err;
1504   }
1505
1506   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1507
1508   /* Compute the shared secret key */
1509   KEY = silc_calloc(1, sizeof(*KEY));
1510   silc_mp_init(KEY);
1511   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1512   ske->KEY = KEY;
1513
1514   /* Decode the remote's public key */
1515   if (payload->pk_data &&
1516       !silc_pkcs_public_key_alloc(payload->pk_type,
1517                                   payload->pk_data, payload->pk_len,
1518                                   &ske->prop->public_key)) {
1519     SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1520     status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1521     goto err;
1522   }
1523
1524   if (ske->prop->public_key && (ske->callbacks->verify_key ||
1525                                 ske->repository)) {
1526     SILC_LOG_DEBUG(("Verifying public key"));
1527
1528     /** Waiting public key verification */
1529     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1530
1531     /* If repository is provided, verify the key from there. */
1532     if (ske->repository) {
1533       SilcSKRFind find;
1534
1535       find = silc_skr_find_alloc();
1536       if (!find) {
1537         status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1538         goto err;
1539       }
1540       silc_skr_find_set_pkcs_type(find,
1541                                   silc_pkcs_get_type(ske->prop->public_key));
1542       silc_skr_find_set_public_key(find, ske->prop->public_key);
1543       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1544
1545       /* Find key from repository */
1546       SILC_FSM_CALL(silc_skr_find(ske->repository, silc_fsm_get_schedule(fsm),
1547                                   find, silc_ske_skr_callback, ske));
1548     } else {
1549       /* Verify from application */
1550       SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1551                                                ske->callbacks->context,
1552                                                silc_ske_pk_verified, NULL));
1553     }
1554     /* NOT REACHED */
1555   }
1556
1557   /** Process key material */
1558   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1559   return SILC_FSM_CONTINUE;
1560
1561  err:
1562   silc_ske_payload_ke_free(payload);
1563   ske->ke2_payload = NULL;
1564
1565   silc_mp_uninit(ske->KEY);
1566   silc_free(ske->KEY);
1567   ske->KEY = NULL;
1568
1569   if (status == SILC_SKE_STATUS_OK)
1570     return SILC_SKE_STATUS_ERROR;
1571
1572   /** Error */
1573   ske->status = status;
1574   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1575   return SILC_FSM_CONTINUE;
1576 }
1577
1578 /* Process key material */
1579
1580 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1581 {
1582   SilcSKE ske = fsm_context;
1583   SilcSKEStatus status;
1584   SilcSKEKEPayload payload;
1585   unsigned char hash[SILC_HASH_MAXLEN];
1586   SilcUInt32 hash_len;
1587   int key_len, block_len;
1588
1589   if (ske->aborted) {
1590     /** Aborted */
1591     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1592     return SILC_FSM_CONTINUE;
1593   }
1594
1595   /* Check result of public key verification */
1596   if (ske->status != SILC_SKE_STATUS_OK) {
1597     /** Public key not verified */
1598     SILC_LOG_DEBUG(("Public key verification failed"));
1599     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1600     return SILC_FSM_CONTINUE;
1601   }
1602
1603   payload = ske->ke2_payload;
1604
1605   /* Compute the HASH value */
1606   SILC_LOG_DEBUG(("Computing HASH value"));
1607   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1608   if (status != SILC_SKE_STATUS_OK)
1609     goto err;
1610   ske->hash = silc_memdup(hash, hash_len);
1611   ske->hash_len = hash_len;
1612
1613   if (ske->prop->public_key) {
1614     SILC_LOG_DEBUG(("Public key is authentic"));
1615     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1616
1617     /* Verify signature */
1618     if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1619                           payload->sign_len, hash, hash_len, NULL)) {
1620       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1621       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1622       goto err;
1623     }
1624
1625     SILC_LOG_DEBUG(("Signature is Ok"));
1626     memset(hash, 'F', hash_len);
1627   }
1628
1629   ske->status = SILC_SKE_STATUS_OK;
1630
1631   /* In case we are doing rekey move to finish it.  */
1632   if (ske->rekey) {
1633     /** Finish rekey */
1634     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1635     return SILC_FSM_CONTINUE;
1636   }
1637
1638   /* Process key material */
1639   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1640   block_len = silc_cipher_get_block_len(ske->prop->cipher);
1641   hash_len = silc_hash_len(ske->prop->hash);
1642   ske->keymat = silc_ske_process_key_material(ske, block_len,
1643                                               key_len, hash_len,
1644                                               &ske->rekey);
1645   if (!ske->keymat) {
1646     SILC_LOG_ERROR(("Error processing key material"));
1647     status = SILC_SKE_STATUS_ERROR;
1648     goto err;
1649   }
1650
1651   /* Send SUCCESS packet */
1652   SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1653   if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1654     /** Error sending packet */
1655     SILC_LOG_DEBUG(("Error sending packet"));
1656     ske->status = SILC_SKE_STATUS_ERROR;
1657     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1658     return SILC_FSM_CONTINUE;
1659   }
1660
1661   /** Waiting completion */
1662   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1663   return SILC_FSM_WAIT;
1664
1665  err:
1666   memset(hash, 'F', sizeof(hash));
1667   silc_ske_payload_ke_free(payload);
1668   ske->ke2_payload = NULL;
1669
1670   silc_mp_uninit(ske->KEY);
1671   silc_free(ske->KEY);
1672   ske->KEY = NULL;
1673
1674   if (ske->hash) {
1675     memset(ske->hash, 'F', hash_len);
1676     silc_free(ske->hash);
1677     ske->hash = NULL;
1678   }
1679
1680   if (status == SILC_SKE_STATUS_OK)
1681     status = SILC_SKE_STATUS_ERROR;
1682
1683   /** Error */
1684   ske->status = status;
1685   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1686   return SILC_FSM_CONTINUE;
1687 }
1688
1689 /* Protocol completed */
1690
1691 SILC_FSM_STATE(silc_ske_st_initiator_end)
1692 {
1693   SilcSKE ske = fsm_context;
1694
1695   SILC_LOG_DEBUG(("Start"));
1696
1697   if (ske->packet->type != SILC_PACKET_SUCCESS) {
1698     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1699     silc_ske_install_retransmission(ske);
1700     silc_packet_free(ske->packet);
1701     ske->packet = NULL;
1702     return SILC_FSM_WAIT;
1703   }
1704
1705   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1706
1707   silc_packet_free(ske->packet);
1708   ske->packet = NULL;
1709   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1710   silc_schedule_task_del_by_context(ske->schedule, ske);
1711
1712   /* Call completion */
1713   silc_ske_completion(ske);
1714
1715   return SILC_FSM_FINISH;
1716 }
1717
1718 /* Aborted by application */
1719
1720 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1721 {
1722   SilcSKE ske = fsm_context;
1723   unsigned char data[4];
1724
1725   SILC_LOG_DEBUG(("Aborted by caller"));
1726
1727   /* Send FAILURE packet */
1728   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1729   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1730
1731   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1732   silc_schedule_task_del_by_context(ske->schedule, ske);
1733
1734   /* Call completion */
1735   silc_ske_completion(ske);
1736
1737   return SILC_FSM_FINISH;
1738 }
1739
1740 /* Error occurred.  Send error to remote host */
1741
1742 SILC_FSM_STATE(silc_ske_st_initiator_error)
1743 {
1744   SilcSKE ske = fsm_context;
1745   SilcSKEStatus status;
1746   unsigned char data[4];
1747
1748   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1749                   silc_ske_map_status(ske->status), ske->status));
1750
1751   status = ske->status;
1752   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1753     status = SILC_SKE_STATUS_ERROR;
1754
1755   /* Send FAILURE packet */
1756   SILC_PUT32_MSB((SilcUInt32)status, data);
1757   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1758
1759   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1760   silc_schedule_task_del_by_context(ske->schedule, ske);
1761
1762   /* Call completion */
1763   silc_ske_completion(ske);
1764
1765   return SILC_FSM_FINISH;
1766 }
1767
1768 /* Failure received from remote */
1769
1770 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1771 {
1772   SilcSKE ske = fsm_context;
1773   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1774
1775   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1776     SILC_GET32_MSB(error, ske->packet->buffer.data);
1777     ske->status = error;
1778     silc_packet_free(ske->packet);
1779     ske->packet = NULL;
1780   }
1781
1782   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1783                   silc_ske_map_status(ske->status), ske->status));
1784
1785   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1786   silc_schedule_task_del_by_context(ske->schedule, ske);
1787
1788   /* Call completion */
1789   silc_ske_completion(ske);
1790
1791   return SILC_FSM_FINISH;
1792 }
1793
1794 /* Starts the protocol as initiator */
1795
1796 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1797                                       SilcPacketStream stream,
1798                                       SilcSKEParams params,
1799                                       SilcSKEStartPayload start_payload)
1800 {
1801   SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload));
1802
1803   if (!ske || !stream || !params || !params->version)
1804     return NULL;
1805
1806   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1807     return NULL;
1808
1809   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1810     return NULL;
1811
1812   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1813     ske->session_port = params->session_port;
1814
1815   /* Generate security properties if not provided */
1816   if (!start_payload) {
1817     start_payload = silc_ske_assemble_security_properties(ske,
1818                                                           params->flags,
1819                                                           params->version);
1820     if (!start_payload)
1821       return NULL;
1822   }
1823
1824   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1825   ske->start_payload = start_payload;
1826   ske->version = params->version;
1827   ++ ske->refcnt;
1828
1829   /* Link to packet stream to get key exchange packets */
1830   ske->stream = stream;
1831   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1832                           SILC_PACKET_KEY_EXCHANGE,
1833                           SILC_PACKET_KEY_EXCHANGE_2,
1834                           SILC_PACKET_SUCCESS,
1835                           SILC_PACKET_FAILURE, -1);
1836
1837   /* Start SKE as initiator */
1838   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1839
1840   return &ske->op;
1841 }
1842
1843 /******************************** Responder *********************************/
1844
1845 /* Start protocol as responder.  Wait initiator's start payload */
1846
1847 SILC_FSM_STATE(silc_ske_st_responder_start)
1848 {
1849   SilcSKE ske = fsm_context;
1850
1851   SILC_LOG_DEBUG(("Start"));
1852
1853   if (ske->aborted) {
1854     /** Aborted */
1855     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1856     return SILC_FSM_CONTINUE;
1857   }
1858
1859   /* Add key exchange timeout */
1860   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1861                                  ske, ske->timeout, 0);
1862
1863   /** Wait for initiator */
1864   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1865   return SILC_FSM_WAIT;
1866 }
1867
1868 /* Decode initiator's start payload.  Select the security properties from
1869    the initiator's start payload and send our reply start payload back. */
1870
1871 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1872 {
1873   SilcSKE ske = fsm_context;
1874   SilcSKEStatus status;
1875   SilcSKEStartPayload remote_payload = NULL;
1876   SilcBuffer packet_buf = &ske->packet->buffer;
1877   SilcID id;
1878
1879   SILC_LOG_DEBUG(("Start"));
1880
1881   /* Decode the payload */
1882   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1883   if (status != SILC_SKE_STATUS_OK) {
1884     /** Error decoding Start Payload */
1885     silc_packet_free(ske->packet);
1886     ske->packet = NULL;
1887     ske->status = status;
1888     silc_fsm_next(fsm, silc_ske_st_responder_error);
1889     return SILC_FSM_CONTINUE;
1890   }
1891
1892   /* Get remote ID and set it to stream */
1893   if (ske->packet->src_id_len) {
1894     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1895                    ske->packet->src_id_type,
1896                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1897                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1898                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1899                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1900     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1901                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1902                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1903   }
1904
1905   /* Take a copy of the payload buffer for future use. It is used to
1906      compute the HASH value. */
1907   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1908
1909   silc_packet_free(ske->packet);
1910   ske->packet = NULL;
1911
1912   /* Force the mutual authentication flag if we want to do it. */
1913   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1914     SILC_LOG_DEBUG(("Force mutual authentication"));
1915     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1916   }
1917
1918   /* Force PFS flag if we require it */
1919   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1920     SILC_LOG_DEBUG(("Force PFS"));
1921     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1922   }
1923
1924   /* Disable IV Included flag if requested */
1925   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1926       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1927     SILC_LOG_DEBUG(("We do not support IV Included flag"));
1928     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1929   }
1930
1931   /* Check and select security properties */
1932   status = silc_ske_select_security_properties(ske, remote_payload,
1933                                                &ske->prop);
1934   if (status != SILC_SKE_STATUS_OK) {
1935     /** Error selecting proposal */
1936     silc_ske_payload_start_free(remote_payload);
1937     ske->status = status;
1938     silc_fsm_next(fsm, silc_ske_st_responder_error);
1939     return SILC_FSM_CONTINUE;
1940   }
1941
1942   silc_ske_payload_start_free(remote_payload);
1943
1944   /* Encode our reply payload to send the selected security properties */
1945   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1946                                          &packet_buf);
1947   if (status != SILC_SKE_STATUS_OK)
1948     goto err;
1949
1950   /* Send the packet. */
1951   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1952                             silc_buffer_data(packet_buf),
1953                             silc_buffer_len(packet_buf)))
1954     goto err;
1955
1956   silc_buffer_free(packet_buf);
1957
1958   /** Waiting initiator's KE payload */
1959   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1960   return SILC_FSM_WAIT;
1961
1962  err:
1963   if (ske->prop->group)
1964     silc_ske_group_free(ske->prop->group);
1965   if (ske->prop->cipher)
1966     silc_cipher_free(ske->prop->cipher);
1967   if (ske->prop->hash)
1968     silc_hash_free(ske->prop->hash);
1969   if (ske->prop->hmac)
1970     silc_hmac_free(ske->prop->hmac);
1971   silc_free(ske->prop);
1972   ske->prop = NULL;
1973
1974   if (status == SILC_SKE_STATUS_OK)
1975     status = SILC_SKE_STATUS_ERROR;
1976
1977   /** Error */
1978   ske->status = status;
1979   silc_fsm_next(fsm, silc_ske_st_responder_error);
1980   return SILC_FSM_CONTINUE;
1981 }
1982
1983 /* Phase-2.  Decode initiator's KE payload */
1984
1985 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1986 {
1987   SilcSKE ske = fsm_context;
1988   SilcSKEStatus status;
1989   SilcSKEKEPayload recv_payload;
1990   SilcBuffer packet_buf = &ske->packet->buffer;
1991
1992   SILC_LOG_DEBUG(("Start"));
1993
1994   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1995     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1996     silc_ske_install_retransmission(ske);
1997     silc_packet_free(ske->packet);
1998     ske->packet = NULL;
1999     return SILC_FSM_WAIT;
2000   }
2001
2002   /* Decode Key Exchange Payload */
2003   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2004   if (status != SILC_SKE_STATUS_OK) {
2005     /** Error decoding KE payload */
2006     silc_packet_free(ske->packet);
2007     ske->packet = NULL;
2008     ske->status = status;
2009     silc_fsm_next(fsm, silc_ske_st_responder_error);
2010     return SILC_FSM_CONTINUE;
2011   }
2012
2013   ske->ke1_payload = recv_payload;
2014
2015   silc_packet_free(ske->packet);
2016   ske->packet = NULL;
2017
2018   /* Verify public key, except in rekey, when it is not sent */
2019   if (!ske->rekey) {
2020     if (!recv_payload->pk_data) {
2021       /** Public key not provided */
2022       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2023                       "certificate), even though we require it"));
2024       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2025       silc_fsm_next(fsm, silc_ske_st_responder_error);
2026       return SILC_FSM_CONTINUE;
2027     }
2028
2029     /* Decode the remote's public key */
2030     if (!silc_pkcs_public_key_alloc(recv_payload->pk_type,
2031                                     recv_payload->pk_data,
2032                                     recv_payload->pk_len,
2033                                     &ske->prop->public_key)) {
2034       /** Error decoding public key */
2035       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2036       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2037       silc_fsm_next(fsm, silc_ske_st_responder_error);
2038       return SILC_FSM_CONTINUE;
2039     }
2040
2041     SILC_LOG_DEBUG(("Verifying public key"));
2042
2043     /** Waiting public key verification */
2044     silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2045
2046     /* If repository is provided, verify the key from there. */
2047     if (ske->repository) {
2048       SilcSKRFind find;
2049
2050       find = silc_skr_find_alloc();
2051       if (!find) {
2052         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2053         silc_fsm_next(fsm, silc_ske_st_responder_error);
2054         return SILC_FSM_CONTINUE;
2055       }
2056       silc_skr_find_set_pkcs_type(find,
2057                                   silc_pkcs_get_type(ske->prop->public_key));
2058       silc_skr_find_set_public_key(find, ske->prop->public_key);
2059       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2060
2061       /* Find key from repository */
2062       SILC_FSM_CALL(silc_skr_find(ske->repository,
2063                                   silc_fsm_get_schedule(fsm), find,
2064                                   silc_ske_skr_callback, ske));
2065     } else {
2066       /* Verify from application */
2067       if (ske->callbacks->verify_key)
2068         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2069                                                  ske->callbacks->context,
2070                                                  silc_ske_pk_verified, NULL));
2071     }
2072   }
2073
2074   /** Generate KE2 payload */
2075   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2076   return SILC_FSM_CONTINUE;
2077 }
2078
2079 /* Phase-4. Generate KE2 payload */
2080
2081 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2082 {
2083   SilcSKE ske = fsm_context;
2084   SilcSKEStatus status;
2085   SilcSKEKEPayload recv_payload, send_payload;
2086   SilcMPInt *x, *KEY;
2087
2088   if (ske->aborted) {
2089     /** Aborted */
2090     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2091     return SILC_FSM_CONTINUE;
2092   }
2093
2094   /* Check result of public key verification */
2095   if (ske->status != SILC_SKE_STATUS_OK) {
2096     /** Public key not verified */
2097     SILC_LOG_DEBUG(("Public key verification failed"));
2098     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2099     return SILC_FSM_CONTINUE;
2100   }
2101
2102   recv_payload = ske->ke1_payload;
2103
2104   /* The public key verification was performed only if the Mutual
2105      Authentication flag is set. */
2106   if (ske->start_payload &&
2107       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2108     unsigned char hash[SILC_HASH_MAXLEN];
2109     SilcUInt32 hash_len;
2110
2111     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2112
2113     /* Compute the hash value */
2114     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2115     if (status != SILC_SKE_STATUS_OK) {
2116       /** Error computing hash */
2117       ske->status = status;
2118       silc_fsm_next(fsm, silc_ske_st_responder_error);
2119       return SILC_FSM_CONTINUE;
2120     }
2121
2122     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2123
2124     /* Verify signature */
2125     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2126                           recv_payload->sign_len, hash, hash_len, NULL)) {
2127       /** Incorrect signature */
2128       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2129       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2130       silc_fsm_next(fsm, silc_ske_st_responder_error);
2131       return SILC_FSM_CONTINUE;
2132     }
2133
2134     SILC_LOG_DEBUG(("Signature is Ok"));
2135
2136     memset(hash, 'F', hash_len);
2137   }
2138
2139   /* Create the random number x, 1 < x < q. */
2140   x = silc_calloc(1, sizeof(*x));
2141   silc_mp_init(x);
2142   status =
2143     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2144                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2145                         x);
2146   if (status != SILC_SKE_STATUS_OK) {
2147     /** Error generating random number */
2148     silc_mp_uninit(x);
2149     silc_free(x);
2150     ske->status = status;
2151     silc_fsm_next(fsm, silc_ske_st_responder_error);
2152     return SILC_FSM_CONTINUE;
2153   }
2154
2155   /* Save the results for later processing */
2156   send_payload = silc_calloc(1, sizeof(*send_payload));
2157   ske->x = x;
2158   ske->ke2_payload = send_payload;
2159
2160   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2161
2162   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2163   silc_mp_init(&send_payload->x);
2164   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2165                   &ske->prop->group->group);
2166
2167   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2168
2169   /* Compute the shared secret key */
2170   KEY = silc_calloc(1, sizeof(*KEY));
2171   silc_mp_init(KEY);
2172   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2173                   &ske->prop->group->group);
2174   ske->KEY = KEY;
2175
2176   /** Send KE2 payload */
2177   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2178   return SILC_FSM_CONTINUE;
2179 }
2180
2181 /* Phase-5.  Send KE2 payload */
2182
2183 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2184 {
2185   SilcSKE ske = fsm_context;
2186   SilcSKEStatus status;
2187   SilcBuffer payload_buf;
2188   unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2189   SilcUInt32 hash_len, sign_len, pk_len;
2190
2191   SILC_LOG_DEBUG(("Start"));
2192
2193   if (ske->public_key && ske->private_key) {
2194     SILC_LOG_DEBUG(("Getting public key"));
2195
2196     /* Get the public key */
2197     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2198     if (!pk) {
2199       /** Error encoding public key */
2200       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2201       silc_fsm_next(fsm, silc_ske_st_responder_error);
2202       return SILC_FSM_CONTINUE;
2203     }
2204     ske->ke2_payload->pk_data = pk;
2205     ske->ke2_payload->pk_len = pk_len;
2206   }
2207
2208   SILC_LOG_DEBUG(("Computing HASH value"));
2209
2210   /* Compute the hash value */
2211   memset(hash, 0, sizeof(hash));
2212   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2213   if (status != SILC_SKE_STATUS_OK) {
2214     /** Error computing hash */
2215     ske->status = status;
2216     silc_fsm_next(fsm, silc_ske_st_responder_error);
2217     return SILC_FSM_CONTINUE;
2218   }
2219   ske->hash = silc_memdup(hash, hash_len);
2220   ske->hash_len = hash_len;
2221
2222   if (ske->public_key && ske->private_key) {
2223     SILC_LOG_DEBUG(("Signing HASH value"));
2224
2225     /* Sign the hash value */
2226     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2227                         sizeof(sign) - 1, &sign_len, FALSE, ske->prop->hash)) {
2228       /** Error computing signature */
2229       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2230       silc_fsm_next(fsm, silc_ske_st_responder_error);
2231       return SILC_FSM_CONTINUE;
2232     }
2233     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2234     ske->ke2_payload->sign_len = sign_len;
2235     memset(sign, 0, sizeof(sign));
2236   }
2237   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2238
2239   /* Encode the Key Exchange Payload */
2240   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2241                                       &payload_buf);
2242   if (status != SILC_SKE_STATUS_OK) {
2243     /** Error encoding KE payload */
2244     ske->status = status;
2245     silc_fsm_next(fsm, silc_ske_st_responder_error);
2246     return SILC_FSM_CONTINUE;
2247   }
2248
2249   /* Send the packet. */
2250   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2251                             payload_buf->data, silc_buffer_len(payload_buf))) {
2252     SILC_LOG_DEBUG(("Error sending packet"));
2253     ske->status = SILC_SKE_STATUS_ERROR;
2254     silc_fsm_next(fsm, silc_ske_st_responder_error);
2255     return SILC_FSM_CONTINUE;
2256   }
2257
2258   silc_buffer_free(payload_buf);
2259
2260   /* In case we are doing rekey move to finish it. */
2261   if (ske->rekey) {
2262     /** Finish rekey */
2263     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2264     return SILC_FSM_CONTINUE;
2265   }
2266
2267   /** Waiting completion */
2268   silc_fsm_next(fsm, silc_ske_st_responder_end);
2269   return SILC_FSM_WAIT;
2270 }
2271
2272 /* Protocol completed */
2273
2274 SILC_FSM_STATE(silc_ske_st_responder_end)
2275 {
2276   SilcSKE ske = fsm_context;
2277   unsigned char tmp[4];
2278   SilcUInt32 hash_len, key_len, block_len;
2279
2280   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2281     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2282     silc_ske_install_retransmission(ske);
2283     silc_packet_free(ske->packet);
2284     ske->packet = NULL;
2285     return SILC_FSM_WAIT;
2286   }
2287   silc_packet_free(ske->packet);
2288   ske->packet = NULL;
2289
2290   /* Process key material */
2291   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2292   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2293   hash_len = silc_hash_len(ske->prop->hash);
2294   ske->keymat = silc_ske_process_key_material(ske, block_len,
2295                                               key_len, hash_len,
2296                                               &ske->rekey);
2297   if (!ske->keymat) {
2298     /** Error processing key material */
2299     ske->status = SILC_SKE_STATUS_ERROR;
2300     silc_fsm_next(fsm, silc_ske_st_responder_error);
2301     return SILC_FSM_CONTINUE;
2302   }
2303
2304   /* Send SUCCESS packet */
2305   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2306   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2307
2308   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2309   silc_schedule_task_del_by_context(ske->schedule, ske);
2310
2311   /* Call completion */
2312   silc_ske_completion(ske);
2313
2314   return SILC_FSM_FINISH;
2315 }
2316
2317 /* Aborted by application */
2318
2319 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2320 {
2321   SilcSKE ske = fsm_context;
2322   unsigned char tmp[4];
2323
2324   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2325
2326   /* Send FAILURE packet */
2327   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2328   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2329
2330   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2331   silc_schedule_task_del_by_context(ske->schedule, ske);
2332
2333   /* Call completion */
2334   silc_ske_completion(ske);
2335
2336   return SILC_FSM_FINISH;
2337 }
2338
2339 /* Failure received from remote */
2340
2341 SILC_FSM_STATE(silc_ske_st_responder_failure)
2342 {
2343   SilcSKE ske = fsm_context;
2344   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2345
2346   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2347
2348   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2349     SILC_GET32_MSB(error, ske->packet->buffer.data);
2350     ske->status = error;
2351     silc_packet_free(ske->packet);
2352     ske->packet = NULL;
2353   }
2354
2355   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2356   silc_schedule_task_del_by_context(ske->schedule, ske);
2357
2358   /* Call completion */
2359   silc_ske_completion(ske);
2360
2361   return SILC_FSM_FINISH;
2362 }
2363
2364 /* Error occurred */
2365
2366 SILC_FSM_STATE(silc_ske_st_responder_error)
2367 {
2368   SilcSKE ske = fsm_context;
2369   unsigned char tmp[4];
2370
2371   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2372                   ske->status, silc_ske_map_status(ske->status)));
2373
2374   /* Send FAILURE packet */
2375   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2376     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2377   SILC_PUT32_MSB(ske->status, tmp);
2378   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2379
2380   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2381   silc_schedule_task_del_by_context(ske->schedule, ske);
2382
2383   /* Call completion */
2384   silc_ske_completion(ske);
2385
2386   return SILC_FSM_FINISH;
2387 }
2388
2389 /* Starts the protocol as responder. */
2390
2391 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2392                                       SilcPacketStream stream,
2393                                       SilcSKEParams params)
2394 {
2395   SILC_LOG_DEBUG(("Start SKE as responder"));
2396
2397   if (!ske || !stream || !params || !params->version)
2398     return NULL;
2399
2400   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2401     return NULL;
2402
2403   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2404     return NULL;
2405
2406   ske->responder = TRUE;
2407   ske->flags = params->flags;
2408   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2409   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2410     ske->session_port = params->session_port;
2411   ske->version = params->version;
2412   if (!ske->version)
2413     return NULL;
2414   ++ ske->refcnt;
2415
2416   /* Link to packet stream to get key exchange packets */
2417   ske->stream = stream;
2418   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2419                           SILC_PACKET_KEY_EXCHANGE,
2420                           SILC_PACKET_KEY_EXCHANGE_1,
2421                           SILC_PACKET_SUCCESS,
2422                           SILC_PACKET_FAILURE, -1);
2423
2424   /* Start SKE as responder */
2425   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2426
2427   return &ske->op;
2428 }
2429
2430 /***************************** Initiator Rekey ******************************/
2431
2432 /* Start rekey */
2433
2434 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2435 {
2436   SilcSKE ske = fsm_context;
2437   SilcStatus status;
2438
2439   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2440
2441   if (ske->aborted) {
2442     /** Aborted */
2443     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2444     return SILC_FSM_CONTINUE;
2445   }
2446
2447   /* Add rekey exchange timeout */
2448   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2449                                  ske, 30, 0);
2450
2451   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2452   if (!ske->prop) {
2453     /** No memory */
2454     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2455     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2456     return SILC_FSM_CONTINUE;
2457   }
2458
2459   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2460     /** Cannot allocate hash */
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   /* Send REKEY packet to start rekey protocol */
2467   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2468     /** Error sending packet */
2469     SILC_LOG_DEBUG(("Error sending packet"));
2470     ske->status = SILC_SKE_STATUS_ERROR;
2471     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2472     return SILC_FSM_CONTINUE;
2473   }
2474
2475   /* If doing rekey without PFS, move directly to the end of the protocol. */
2476   if (!ske->rekey->pfs) {
2477     /** Rekey without PFS */
2478     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2479     return SILC_FSM_CONTINUE;
2480   }
2481
2482   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2483                                         &ske->prop->group);
2484   if (status != SILC_SKE_STATUS_OK) {
2485     /** Unknown group */
2486     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2487     return SILC_FSM_CONTINUE;
2488   }
2489
2490   /** Rekey with PFS */
2491   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2492   return SILC_FSM_CONTINUE;
2493 }
2494
2495 /* Sends REKEY_DONE packet to finish the protocol. */
2496
2497 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2498 {
2499   SilcSKE ske = fsm_context;
2500   SilcCipher send_key;
2501   SilcHmac hmac_send;
2502   SilcHash hash;
2503   SilcUInt32 key_len, block_len, hash_len, x_len;
2504   unsigned char *pfsbuf;
2505
2506   SILC_LOG_DEBUG(("Start"));
2507
2508   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2509   key_len = silc_cipher_get_key_len(send_key);
2510   block_len = silc_cipher_get_block_len(send_key);
2511   hash = ske->prop->hash;
2512   hash_len = silc_hash_len(hash);
2513
2514   /* Process key material */
2515   if (ske->rekey->pfs) {
2516     /* PFS */
2517     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2518     if (pfsbuf) {
2519       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2520                                                        block_len, key_len,
2521                                                        hash_len, hash);
2522       memset(pfsbuf, 0, x_len);
2523       silc_free(pfsbuf);
2524     }
2525   } else {
2526     /* No PFS */
2527     ske->keymat =
2528       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2529                                          ske->rekey->enc_key_len / 8,
2530                                          block_len, key_len,
2531                                          hash_len, hash);
2532   }
2533
2534   if (!ske->keymat) {
2535     SILC_LOG_ERROR(("Error processing key material"));
2536     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2537     return SILC_FSM_CONTINUE;
2538   }
2539
2540   ske->prop->cipher = send_key;
2541   ske->prop->hmac = hmac_send;
2542
2543   /* Get sending keys */
2544   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2545                          &hmac_send, NULL, NULL)) {
2546     /** Cannot get keys */
2547     ske->status = SILC_SKE_STATUS_ERROR;
2548     ske->prop->cipher = NULL;
2549     ske->prop->hmac = NULL;
2550     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2551     return SILC_FSM_CONTINUE;
2552   }
2553
2554   ske->prop->cipher = NULL;
2555   ske->prop->hmac = NULL;
2556
2557   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2558      packet sent after this call will be protected with the new keys. */
2559   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2560                             TRUE)) {
2561     /** Cannot set keys */
2562     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2563     ske->status = SILC_SKE_STATUS_ERROR;
2564     silc_cipher_free(send_key);
2565     silc_hmac_free(hmac_send);
2566     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2567     return SILC_FSM_CONTINUE;
2568   }
2569
2570   /** Wait for REKEY_DONE */
2571   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2572   return SILC_FSM_WAIT;
2573 }
2574
2575 /* Rekey protocol end */
2576
2577 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2578 {
2579   SilcSKE ske = fsm_context;
2580   SilcCipher receive_key;
2581   SilcHmac hmac_receive;
2582   SilcSKERekeyMaterial rekey;
2583
2584   SILC_LOG_DEBUG(("Start"));
2585
2586   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2587     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2588     silc_packet_free(ske->packet);
2589     ske->packet = NULL;
2590     return SILC_FSM_WAIT;
2591   }
2592
2593   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2594   ske->prop->cipher = receive_key;
2595   ske->prop->hmac = hmac_receive;
2596
2597   /* Get receiving keys */
2598   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2599                          NULL, &hmac_receive, NULL)) {
2600     /** Cannot get keys */
2601     ske->status = SILC_SKE_STATUS_ERROR;
2602     ske->prop->cipher = NULL;
2603     ske->prop->hmac = NULL;
2604     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2605     return SILC_FSM_CONTINUE;
2606   }
2607
2608   /* Set new receiving keys into use.  All packets received after this will
2609      be decrypted with the new keys. */
2610   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2611                             hmac_receive, FALSE)) {
2612     /** Cannot set keys */
2613     SILC_LOG_DEBUG(("Cannot set new keys"));
2614     ske->status = SILC_SKE_STATUS_ERROR;
2615     silc_cipher_free(receive_key);
2616     silc_hmac_free(hmac_receive);
2617     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2618     return SILC_FSM_CONTINUE;
2619   }
2620
2621   SILC_LOG_DEBUG(("Rekey completed successfully"));
2622
2623   /* Generate new rekey material */
2624   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2625   if (!rekey) {
2626     /** No memory */
2627     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2628     ske->prop->cipher = NULL;
2629     ske->prop->hmac = NULL;
2630     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2631     return SILC_FSM_CONTINUE;
2632   }
2633   rekey->pfs = ske->rekey->pfs;
2634   ske->rekey = rekey;
2635
2636   ske->prop->cipher = NULL;
2637   ske->prop->hmac = NULL;
2638   silc_packet_free(ske->packet);
2639   ske->packet = NULL;
2640   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2641   silc_schedule_task_del_by_context(ske->schedule, ske);
2642
2643   /* Call completion */
2644   silc_ske_completion(ske);
2645
2646   return SILC_FSM_FINISH;
2647 }
2648
2649 /* Starts rekey protocol as initiator */
2650
2651 SilcAsyncOperation
2652 silc_ske_rekey_initiator(SilcSKE ske,
2653                          SilcPacketStream stream,
2654                          SilcSKERekeyMaterial rekey)
2655 {
2656   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2657
2658   if (!ske || !stream || !rekey) {
2659     SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2660     SILC_ASSERT(rekey);
2661     return NULL;
2662   }
2663
2664   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2665     return NULL;
2666
2667   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2668     return NULL;
2669
2670   ske->rekey = rekey;
2671   ske->responder = FALSE;
2672   ske->rekeying = TRUE;
2673   ++ ske->refcnt;
2674
2675   /* Link to packet stream to get key exchange packets */
2676   ske->stream = stream;
2677   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2678                           SILC_PACKET_REKEY,
2679                           SILC_PACKET_REKEY_DONE,
2680                           SILC_PACKET_KEY_EXCHANGE_2,
2681                           SILC_PACKET_SUCCESS,
2682                           SILC_PACKET_FAILURE, -1);
2683
2684   /* Start SKE rekey as initiator */
2685   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2686
2687   return &ske->op;
2688 }
2689
2690 /***************************** Responder Rekey ******************************/
2691
2692 /* Wait for initiator's packet */
2693
2694 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2695 {
2696   SilcSKE ske = fsm_context;
2697
2698   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2699
2700   if (ske->aborted) {
2701     /** Aborted */
2702     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2703     return SILC_FSM_CONTINUE;
2704   }
2705
2706   /* Add rekey exchange timeout */
2707   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2708                                  ske, 30, 0);
2709
2710   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2711
2712   /* If REKEY packet already received process it directly */
2713   if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2714     return SILC_FSM_CONTINUE;
2715
2716   /* Wait for REKEY */
2717   return SILC_FSM_WAIT;
2718 }
2719
2720 /* Process initiator's REKEY packet */
2721
2722 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2723 {
2724   SilcSKE ske = fsm_context;
2725   SilcSKEStatus status;
2726
2727   SILC_LOG_DEBUG(("Start"));
2728
2729   if (ske->packet->type != SILC_PACKET_REKEY) {
2730     ske->status = SILC_SKE_STATUS_ERROR;
2731     silc_packet_free(ske->packet);
2732     ske->packet = NULL;
2733     silc_fsm_next(fsm, silc_ske_st_responder_error);
2734     return SILC_FSM_CONTINUE;
2735   }
2736
2737   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2738   if (!ske->prop) {
2739     /** No memory */
2740     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2741     silc_fsm_next(fsm, silc_ske_st_responder_error);
2742     return SILC_FSM_CONTINUE;
2743   }
2744
2745   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2746     /** Cannot allocate hash */
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 doing rekey without PFS, move directly to the end of the protocol. */
2753   if (!ske->rekey->pfs) {
2754     /** Rekey without PFS */
2755     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2756     return SILC_FSM_CONTINUE;
2757   }
2758
2759   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2760                                         &ske->prop->group);
2761   if (status != SILC_SKE_STATUS_OK) {
2762     /** Unknown group */
2763     silc_fsm_next(fsm, silc_ske_st_responder_error);
2764     return SILC_FSM_CONTINUE;
2765   }
2766
2767   /** Rekey with PFS */
2768   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2769   return SILC_FSM_WAIT;
2770 }
2771
2772 /* Sends REKEY_DONE packet to finish the protocol. */
2773
2774 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2775 {
2776   SilcSKE ske = fsm_context;
2777   SilcCipher send_key;
2778   SilcHmac hmac_send;
2779   SilcHash hash;
2780   SilcUInt32 key_len, block_len, hash_len, x_len;
2781   unsigned char *pfsbuf;
2782
2783   SILC_LOG_DEBUG(("Start"));
2784
2785   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2786   key_len = silc_cipher_get_key_len(send_key);
2787   block_len = silc_cipher_get_block_len(send_key);
2788   hash = ske->prop->hash;
2789   hash_len = silc_hash_len(hash);
2790
2791   /* Process key material */
2792   if (ske->rekey->pfs) {
2793     /* PFS */
2794     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2795     if (pfsbuf) {
2796       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2797                                                        block_len, key_len,
2798                                                        hash_len, hash);
2799       memset(pfsbuf, 0, x_len);
2800       silc_free(pfsbuf);
2801     }
2802   } else {
2803     /* No PFS */
2804     ske->keymat =
2805       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2806                                          ske->rekey->enc_key_len / 8,
2807                                          block_len, key_len,
2808                                          hash_len, hash);
2809   }
2810
2811   if (!ske->keymat) {
2812     SILC_LOG_ERROR(("Error processing key material"));
2813     silc_fsm_next(fsm, silc_ske_st_responder_error);
2814     return SILC_FSM_CONTINUE;
2815   }
2816
2817   ske->prop->cipher = send_key;
2818   ske->prop->hmac = hmac_send;
2819
2820   /* Get sending keys */
2821   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2822                          &hmac_send, NULL, NULL)) {
2823     /** Cannot get keys */
2824     ske->status = SILC_SKE_STATUS_ERROR;
2825     ske->prop->cipher = NULL;
2826     ske->prop->hmac = NULL;
2827     silc_fsm_next(fsm, silc_ske_st_responder_error);
2828     return SILC_FSM_CONTINUE;
2829   }
2830
2831   ske->prop->cipher = NULL;
2832   ske->prop->hmac = NULL;
2833
2834   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2835      packet sent after this call will be protected with the new keys. */
2836   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2837                             TRUE)) {
2838     /** Cannot set keys */
2839     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2840     ske->status = SILC_SKE_STATUS_ERROR;
2841     silc_cipher_free(send_key);
2842     silc_hmac_free(hmac_send);
2843     silc_fsm_next(fsm, silc_ske_st_responder_error);
2844     return SILC_FSM_CONTINUE;
2845   }
2846
2847   /** Wait for REKEY_DONE */
2848   silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2849   return SILC_FSM_WAIT;
2850 }
2851
2852 /* Rekey protocol end */
2853
2854 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2855 {
2856   SilcSKE ske = fsm_context;
2857   SilcCipher receive_key;
2858   SilcHmac hmac_receive;
2859   SilcSKERekeyMaterial rekey;
2860
2861   SILC_LOG_DEBUG(("Start"));
2862
2863   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2864     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2865     silc_packet_free(ske->packet);
2866     ske->packet = NULL;
2867     return SILC_FSM_WAIT;
2868   }
2869
2870   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2871   ske->prop->cipher = receive_key;
2872   ske->prop->hmac = hmac_receive;
2873
2874   /* Get receiving keys */
2875   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2876                          NULL, &hmac_receive, NULL)) {
2877     /** Cannot get keys */
2878     ske->status = SILC_SKE_STATUS_ERROR;
2879     ske->prop->cipher = NULL;
2880     ske->prop->hmac = NULL;
2881     silc_fsm_next(fsm, silc_ske_st_responder_error);
2882     return SILC_FSM_CONTINUE;
2883   }
2884
2885   /* Set new receiving keys into use.  All packets received after this will
2886      be decrypted with the new keys. */
2887   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2888                             hmac_receive, FALSE)) {
2889     /** Cannot set keys */
2890     SILC_LOG_DEBUG(("Cannot set new keys"));
2891     ske->status = SILC_SKE_STATUS_ERROR;
2892     ske->prop->cipher = NULL;
2893     ske->prop->hmac = NULL;
2894     silc_cipher_free(receive_key);
2895     silc_hmac_free(hmac_receive);
2896     silc_fsm_next(fsm, silc_ske_st_responder_error);
2897     return SILC_FSM_CONTINUE;
2898   }
2899
2900   SILC_LOG_DEBUG(("Rekey completed successfully"));
2901
2902   /* Generate new rekey material */
2903   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2904   if (!rekey) {
2905     /** No memory */
2906     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2907     ske->prop->cipher = NULL;
2908     ske->prop->hmac = NULL;
2909     silc_fsm_next(fsm, silc_ske_st_responder_error);
2910     return SILC_FSM_CONTINUE;
2911   }
2912   rekey->pfs = ske->rekey->pfs;
2913   ske->rekey = rekey;
2914
2915   ske->prop->cipher = NULL;
2916   ske->prop->hmac = NULL;
2917   silc_packet_free(ske->packet);
2918   ske->packet = NULL;
2919   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2920   silc_schedule_task_del_by_context(ske->schedule, ske);
2921
2922   /* Call completion */
2923   silc_ske_completion(ske);
2924
2925   return SILC_FSM_FINISH;
2926 }
2927
2928 /* Starts rekey protocol as responder */
2929
2930 SilcAsyncOperation
2931 silc_ske_rekey_responder(SilcSKE ske,
2932                          SilcPacketStream stream,
2933                          SilcSKERekeyMaterial rekey,
2934                          SilcPacket packet)
2935 {
2936   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2937
2938   if (!ske || !stream || !rekey)
2939     return NULL;
2940
2941   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2942     return NULL;
2943
2944   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2945     return NULL;
2946
2947   ske->rekey = rekey;
2948   ske->responder = TRUE;
2949   ske->rekeying = TRUE;
2950   ske->packet = packet;
2951   ++ ske->refcnt;
2952
2953   /* Link to packet stream to get key exchange packets */
2954   ske->stream = stream;
2955   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2956                           SILC_PACKET_REKEY,
2957                           SILC_PACKET_REKEY_DONE,
2958                           SILC_PACKET_KEY_EXCHANGE_1,
2959                           SILC_PACKET_SUCCESS,
2960                           SILC_PACKET_FAILURE, -1);
2961
2962   /* Start SKE rekey as responder */
2963   silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
2964
2965   return &ske->op;
2966 }
2967
2968 /* Processes the provided key material `data' as the SILC protocol
2969    specification defines. */
2970
2971 SilcSKEKeyMaterial
2972 silc_ske_process_key_material_data(unsigned char *data,
2973                                    SilcUInt32 data_len,
2974                                    SilcUInt32 req_iv_len,
2975                                    SilcUInt32 req_enc_key_len,
2976                                    SilcUInt32 req_hmac_key_len,
2977                                    SilcHash hash)
2978 {
2979   SilcBuffer buf;
2980   unsigned char hashd[SILC_HASH_MAXLEN];
2981   SilcUInt32 hash_len = req_hmac_key_len;
2982   SilcUInt32 enc_key_len = req_enc_key_len / 8;
2983   SilcSKEKeyMaterial key;
2984
2985   SILC_LOG_DEBUG(("Start"));
2986
2987   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2988     return NULL;
2989
2990   key = silc_calloc(1, sizeof(*key));
2991   if (!key)
2992     return NULL;
2993
2994   buf = silc_buffer_alloc_size(1 + data_len);
2995   if (!buf)
2996     return NULL;
2997   silc_buffer_format(buf,
2998                      SILC_STR_UI_CHAR(0),
2999                      SILC_STR_DATA(data, data_len),
3000                      SILC_STR_END);
3001
3002   /* Take IVs */
3003   memset(hashd, 0, sizeof(hashd));
3004   buf->data[0] = 0;
3005   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3006   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3007   memcpy(key->send_iv, hashd, req_iv_len);
3008   memset(hashd, 0, sizeof(hashd));
3009   buf->data[0] = 1;
3010   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3011   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3012   memcpy(key->receive_iv, hashd, req_iv_len);
3013   key->iv_len = req_iv_len;
3014
3015   /* Take the encryption keys. If requested key size is more than
3016      the size of hash length we will distribute more key material
3017      as protocol defines. */
3018   buf->data[0] = 2;
3019   if (enc_key_len > hash_len) {
3020     SilcBuffer dist;
3021     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3022         k3[SILC_HASH_MAXLEN];
3023     unsigned char *dtmp;
3024
3025     /* XXX */
3026     if (enc_key_len > (3 * hash_len))
3027       return NULL;
3028
3029     /* Take first round */
3030     memset(k1, 0, sizeof(k1));
3031     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3032
3033     /* Take second round */
3034     dist = silc_buffer_alloc_size(data_len + hash_len);
3035     if (!dist)
3036       return NULL;
3037     silc_buffer_format(dist,
3038                        SILC_STR_DATA(data, data_len),
3039                        SILC_STR_DATA(k1, hash_len),
3040                        SILC_STR_END);
3041     memset(k2, 0, sizeof(k2));
3042     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3043
3044     /* Take third round */
3045     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3046     silc_buffer_pull_tail(dist, hash_len);
3047     silc_buffer_pull(dist, data_len + hash_len);
3048     silc_buffer_format(dist,
3049                        SILC_STR_DATA(k2, hash_len),
3050                        SILC_STR_END);
3051     silc_buffer_push(dist, data_len + hash_len);
3052     memset(k3, 0, sizeof(k3));
3053     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3054
3055     /* Then, save the keys */
3056     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3057     memcpy(dtmp, k1, hash_len);
3058     memcpy(dtmp + hash_len, k2, hash_len);
3059     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3060
3061     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3062     memcpy(key->send_enc_key, dtmp, enc_key_len);
3063     key->enc_key_len = req_enc_key_len;
3064
3065     memset(dtmp, 0, (3 * hash_len));
3066     memset(k1, 0, sizeof(k1));
3067     memset(k2, 0, sizeof(k2));
3068     memset(k3, 0, sizeof(k3));
3069     silc_free(dtmp);
3070     silc_buffer_clear(dist);
3071     silc_buffer_free(dist);
3072   } else {
3073     /* Take normal hash as key */
3074     memset(hashd, 0, sizeof(hashd));
3075     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3076     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3077     memcpy(key->send_enc_key, hashd, enc_key_len);
3078     key->enc_key_len = req_enc_key_len;
3079   }
3080
3081   buf->data[0] = 3;
3082   if (enc_key_len > hash_len) {
3083     SilcBuffer dist;
3084     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3085         k3[SILC_HASH_MAXLEN];
3086     unsigned char *dtmp;
3087
3088     /* XXX */
3089     if (enc_key_len > (3 * hash_len))
3090       return NULL;
3091
3092     /* Take first round */
3093     memset(k1, 0, sizeof(k1));
3094     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3095
3096     /* Take second round */
3097     dist = silc_buffer_alloc_size(data_len + hash_len);
3098     if (!dist)
3099       return NULL;
3100     silc_buffer_format(dist,
3101                        SILC_STR_DATA(data, data_len),
3102                        SILC_STR_DATA(k1, hash_len),
3103                        SILC_STR_END);
3104     memset(k2, 0, sizeof(k2));
3105     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3106
3107     /* Take third round */
3108     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3109     silc_buffer_pull_tail(dist, hash_len);
3110     silc_buffer_pull(dist, data_len + hash_len);
3111     silc_buffer_format(dist,
3112                        SILC_STR_DATA(k2, hash_len),
3113                        SILC_STR_END);
3114     silc_buffer_push(dist, data_len + hash_len);
3115     memset(k3, 0, sizeof(k3));
3116     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3117
3118     /* Then, save the keys */
3119     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3120     memcpy(dtmp, k1, hash_len);
3121     memcpy(dtmp + hash_len, k2, hash_len);
3122     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3123
3124     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3125     memcpy(key->receive_enc_key, dtmp, enc_key_len);
3126     key->enc_key_len = req_enc_key_len;
3127
3128     memset(dtmp, 0, (3 * hash_len));
3129     memset(k1, 0, sizeof(k1));
3130     memset(k2, 0, sizeof(k2));
3131     memset(k3, 0, sizeof(k3));
3132     silc_free(dtmp);
3133     silc_buffer_clear(dist);
3134     silc_buffer_free(dist);
3135   } else {
3136     /* Take normal hash as key */
3137     memset(hashd, 0, sizeof(hashd));
3138     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3139     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3140     memcpy(key->receive_enc_key, hashd, enc_key_len);
3141     key->enc_key_len = req_enc_key_len;
3142   }
3143
3144   /* Take HMAC keys */
3145   memset(hashd, 0, sizeof(hashd));
3146   buf->data[0] = 4;
3147   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3148   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3149   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3150   memset(hashd, 0, sizeof(hashd));
3151   buf->data[0] = 5;
3152   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3153   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3154   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3155   key->hmac_key_len = req_hmac_key_len;
3156   memset(hashd, 0, sizeof(hashd));
3157
3158   silc_buffer_clear(buf);
3159   silc_buffer_free(buf);
3160
3161   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3162
3163   return key;
3164 }
3165
3166 /* Processes negotiated key material as protocol specifies. This returns
3167    the actual keys to be used in the SILC. */
3168
3169 SilcSKEKeyMaterial
3170 silc_ske_process_key_material(SilcSKE ske,
3171                               SilcUInt32 req_iv_len,
3172                               SilcUInt32 req_enc_key_len,
3173                               SilcUInt32 req_hmac_key_len,
3174                               SilcSKERekeyMaterial *rekey)
3175 {
3176   SilcBuffer buf;
3177   unsigned char *tmpbuf;
3178   SilcUInt32 klen;
3179   SilcSKEKeyMaterial key;
3180
3181   /* Encode KEY to binary data */
3182   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3183
3184   buf = silc_buffer_alloc_size(klen + ske->hash_len);
3185   if (!buf)
3186     return NULL;
3187   silc_buffer_format(buf,
3188                      SILC_STR_DATA(tmpbuf, klen),
3189                      SILC_STR_DATA(ske->hash, ske->hash_len),
3190                      SILC_STR_END);
3191
3192   /* Process the key material */
3193   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3194                                            req_iv_len, req_enc_key_len,
3195                                            req_hmac_key_len,
3196                                            ske->prop->hash);
3197
3198   memset(tmpbuf, 0, klen);
3199   silc_free(tmpbuf);
3200   silc_buffer_clear(buf);
3201   silc_buffer_free(buf);
3202
3203   if (rekey) {
3204     *rekey = silc_ske_make_rekey_material(ske, key);
3205     if (!(*rekey))
3206       return NULL;
3207   }
3208
3209   return key;
3210 }
3211
3212 /* Free key material structure */
3213
3214 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3215 {
3216   if (!key)
3217     return;
3218
3219   if (key->send_iv)
3220     silc_free(key->send_iv);
3221   if (key->receive_iv)
3222     silc_free(key->receive_iv);
3223   if (key->send_enc_key) {
3224     memset(key->send_enc_key, 0, key->enc_key_len / 8);
3225     silc_free(key->send_enc_key);
3226   }
3227   if (key->receive_enc_key) {
3228     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3229     silc_free(key->receive_enc_key);
3230   }
3231   if (key->send_hmac_key) {
3232     memset(key->send_hmac_key, 0, key->hmac_key_len);
3233     silc_free(key->send_hmac_key);
3234   }
3235   if (key->receive_hmac_key) {
3236     memset(key->receive_hmac_key, 0, key->hmac_key_len);
3237     silc_free(key->receive_hmac_key);
3238   }
3239   silc_free(key);
3240 }
3241
3242 /* Free rekey material */
3243
3244 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3245 {
3246   if (!rekey)
3247     return;
3248   if (rekey->send_enc_key) {
3249     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3250     silc_free(rekey->send_enc_key);
3251   }
3252   silc_free(rekey->hash);
3253   silc_free(rekey);
3254 }
3255
3256 /* Set keys into use */
3257
3258 SilcBool silc_ske_set_keys(SilcSKE ske,
3259                            SilcSKEKeyMaterial keymat,
3260                            SilcSKESecurityProperties prop,
3261                            SilcCipher *ret_send_key,
3262                            SilcCipher *ret_receive_key,
3263                            SilcHmac *ret_hmac_send,
3264                            SilcHmac *ret_hmac_receive,
3265                            SilcHash *ret_hash)
3266 {
3267   unsigned char iv[SILC_HASH_MAXLEN];
3268   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3269
3270   /* Allocate ciphers to be used in the communication */
3271   if (ret_send_key) {
3272     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3273                            ret_send_key))
3274       return FALSE;
3275   }
3276   if (ret_receive_key) {
3277     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3278                            ret_receive_key))
3279       return FALSE;
3280   }
3281
3282   /* Allocate HMACs */
3283   if (ret_hmac_send) {
3284     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3285                          ret_hmac_send))
3286       return FALSE;
3287   }
3288   if (ret_hmac_receive) {
3289     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3290                          ret_hmac_receive))
3291       return FALSE;
3292   }
3293
3294   /* Allocate hash */
3295   if (ret_hash) {
3296     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3297       return FALSE;
3298   }
3299
3300   /* Set key material */
3301   memset(iv, 0, sizeof(iv));
3302   if (ske->responder) {
3303     if (ret_send_key) {
3304       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3305                           keymat->enc_key_len, TRUE);
3306
3307       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3308         /* Counter mode */
3309         if (!ske->rekeying) {
3310           /* Set IV. */
3311           memcpy(iv, ske->hash, 4);
3312           if (!iv_included)
3313             memcpy(iv + 4, keymat->receive_iv, 8);
3314         } else {
3315           /* Rekey, recompute the truncated hash value. */
3316           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3317           if (!iv_included)
3318             memcpy(iv + 4, keymat->receive_iv, 8);
3319           else
3320             memset(iv + 4, 0, 12);
3321         }
3322
3323         silc_cipher_set_iv(*ret_send_key, iv);
3324       } else {
3325         /* Other modes */
3326         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3327       }
3328     }
3329     if (ret_receive_key) {
3330       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3331                           keymat->enc_key_len, FALSE);
3332
3333       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3334         /* Counter mode */
3335         if (!ske->rekeying) {
3336           /* Set IV. */
3337           memcpy(iv, ske->hash, 4);
3338           if (!iv_included)
3339             memcpy(iv + 4, keymat->send_iv, 8);
3340         } else {
3341           /* Rekey, recompute the truncated hash value. */
3342           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3343           if (!iv_included)
3344             memcpy(iv + 4, keymat->send_iv, 8);
3345           else
3346             memset(iv + 4, 0, 12);
3347         }
3348
3349         silc_cipher_set_iv(*ret_receive_key, iv);
3350       } else {
3351         /* Other modes */
3352         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3353       }
3354     }
3355     if (ret_hmac_send)
3356       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3357                         keymat->hmac_key_len);
3358     if (ret_hmac_receive)
3359       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3360                         keymat->hmac_key_len);
3361   } else {
3362     if (ret_send_key) {
3363       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3364                           keymat->enc_key_len, TRUE);
3365
3366       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3367         /* Counter mode */
3368         if (!ske->rekeying) {
3369           /* Set IV. */
3370           memcpy(iv, ske->hash, 4);
3371           if (!iv_included)
3372             memcpy(iv + 4, keymat->send_iv, 8);
3373         } else {
3374           /* Rekey, recompute the truncated hash value. */
3375           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3376           if (!iv_included)
3377             memcpy(iv + 4, keymat->send_iv, 8);
3378           else
3379             memset(iv + 4, 0, 12);
3380         }
3381
3382         silc_cipher_set_iv(*ret_send_key, iv);
3383       } else {
3384         /* Other modes */
3385         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3386       }
3387     }
3388     if (ret_receive_key) {
3389       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3390                           keymat->enc_key_len, FALSE);
3391
3392       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3393         /* Counter mode */
3394         if (!ske->rekeying) {
3395           /* Set IV.  If IV Included flag was negotiated we only set the
3396              truncated hash value. */
3397           memcpy(iv, ske->hash, 4);
3398           if (!iv_included)
3399             memcpy(iv + 4, keymat->receive_iv, 8);
3400         } else {
3401           /* Rekey, recompute the truncated hash value. */
3402           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3403           if (!iv_included)
3404             memcpy(iv + 4, keymat->receive_iv, 8);
3405           else
3406             memset(iv + 4, 0, 12);
3407         }
3408
3409         silc_cipher_set_iv(*ret_receive_key, iv);
3410       } else {
3411         /* Other modes */
3412         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3413       }
3414     }
3415     if (ret_hmac_send)
3416       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3417                         keymat->hmac_key_len);
3418     if (ret_hmac_receive)
3419       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3420                         keymat->hmac_key_len);
3421   }
3422
3423   return TRUE;
3424 }
3425
3426 const char *silc_ske_status_string[] =
3427 {
3428   /* Official */
3429   "Ok",
3430   "Unexpected error occurred",
3431   "Bad payload in packet",
3432   "Unsupported group",
3433   "Unsupported cipher",
3434   "Unsupported PKCS",
3435   "Unsupported hash function",
3436   "Unsupported HMAC",
3437   "Unsupported public key (or certificate)",
3438   "Incorrect signature",
3439   "Bad or unsupported version",
3440   "Invalid cookie",
3441
3442   /* Other errors */
3443   "Remote did not provide public key",
3444   "Bad reserved field in packet",
3445   "Bad payload length in packet",
3446   "Error computing signature",
3447   "System out of memory",
3448   "Key exchange timeout",
3449
3450   NULL
3451 };
3452
3453 /* Maps status to readable string and returns the string. If string is not
3454    found and empty character string ("") is returned. */
3455
3456 const char *silc_ske_map_status(SilcSKEStatus status)
3457 {
3458   int i;
3459
3460   for (i = 0; silc_ske_status_string[i]; i++)
3461     if (status == i)
3462       return silc_ske_status_string[i];
3463
3464   return "";
3465 }
3466
3467 /* Parses remote host's version string. */
3468
3469 SilcBool silc_ske_parse_version(SilcSKE ske,
3470                                 SilcUInt32 *protocol_version,
3471                                 char **protocol_version_string,
3472                                 SilcUInt32 *software_version,
3473                                 char **software_version_string,
3474                                 char **vendor_version)
3475 {
3476   return silc_parse_version_string(ske->remote_version,
3477                                    protocol_version,
3478                                    protocol_version_string,
3479                                    software_version,
3480                                    software_version_string,
3481                                    vendor_version);
3482 }
3483
3484 /* Get security properties */
3485
3486 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3487 {
3488   return ske->prop;
3489 }
3490
3491 /* Get key material */
3492
3493 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3494 {
3495   return ske->keymat;
3496 }