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