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