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