b3a151e6eaeb7f8f4a5b947cb3b4e11a731a2614
[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(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(ske->prop->public_key, payload->sign_data,
1719                                    payload->sign_len, hash, hash_len, NULL,
1720                                    silc_ske_verify_cb, ske));
1721     /* NOT REACHED */
1722   }
1723
1724   return SILC_FSM_CONTINUE;
1725
1726  err:
1727   memset(hash, 'F', sizeof(hash));
1728   silc_ske_payload_ke_free(payload);
1729   ske->ke2_payload = NULL;
1730
1731   silc_mp_uninit(ske->KEY);
1732   silc_free(ske->KEY);
1733   ske->KEY = NULL;
1734
1735   if (ske->hash) {
1736     memset(ske->hash, 'F', hash_len);
1737     silc_free(ske->hash);
1738     ske->hash = NULL;
1739   }
1740
1741   if (status == SILC_SKE_STATUS_OK)
1742     status = SILC_SKE_STATUS_ERROR;
1743
1744   /** Error */
1745   ske->status = status;
1746   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1747   return SILC_FSM_CONTINUE;
1748 }
1749
1750 /* Process key material */
1751
1752 SILC_FSM_STATE(silc_ske_st_initiator_phase5)
1753 {
1754   SilcSKE ske = fsm_context;
1755   SilcSKEStatus status;
1756   unsigned char tmp[4];
1757   SilcUInt32 hash_len;
1758   int key_len, block_len;
1759
1760   ske->status = SILC_SKE_STATUS_OK;
1761
1762   /* In case we are doing rekey move to finish it.  */
1763   if (ske->rekey) {
1764     /** Finish rekey */
1765     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
1766     return SILC_FSM_CONTINUE;
1767   }
1768
1769   /* Process key material */
1770   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1771   block_len = silc_cipher_get_block_len(ske->prop->cipher);
1772   hash_len = silc_hash_len(ske->prop->hash);
1773   ske->keymat = silc_ske_process_key_material(ske, block_len,
1774                                               key_len, hash_len,
1775                                               &ske->rekey);
1776   if (!ske->keymat) {
1777     SILC_LOG_ERROR(("Error processing key material"));
1778     status = SILC_SKE_STATUS_ERROR;
1779     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1780     return SILC_FSM_CONTINUE;
1781   }
1782
1783   /* Send SUCCESS packet */
1784   SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, tmp);
1785   if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4)) {
1786     /** Error sending packet */
1787     SILC_LOG_DEBUG(("Error sending packet"));
1788     ske->status = SILC_SKE_STATUS_ERROR;
1789     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1790     return SILC_FSM_CONTINUE;
1791   }
1792
1793   /** Waiting completion */
1794   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1795   return SILC_FSM_WAIT;
1796 }
1797
1798 /* Protocol completed */
1799
1800 SILC_FSM_STATE(silc_ske_st_initiator_end)
1801 {
1802   SilcSKE ske = fsm_context;
1803
1804   SILC_LOG_DEBUG(("Start"));
1805
1806   if (ske->packet->type != SILC_PACKET_SUCCESS) {
1807     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1808     silc_ske_install_retransmission(ske);
1809     silc_packet_free(ske->packet);
1810     ske->packet = NULL;
1811     return SILC_FSM_WAIT;
1812   }
1813
1814   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1815
1816   silc_packet_free(ske->packet);
1817   ske->packet = NULL;
1818   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1819   silc_schedule_task_del_by_context(ske->schedule, ske);
1820
1821   /* Call completion */
1822   silc_ske_completion(ske);
1823
1824   return SILC_FSM_FINISH;
1825 }
1826
1827 /* Aborted by application */
1828
1829 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1830 {
1831   SilcSKE ske = fsm_context;
1832   unsigned char data[4];
1833
1834   SILC_LOG_DEBUG(("Aborted by caller"));
1835
1836   /* Send FAILURE packet */
1837   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1838   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1839
1840   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1841   silc_schedule_task_del_by_context(ske->schedule, ske);
1842
1843   /* Call completion */
1844   silc_ske_completion(ske);
1845
1846   return SILC_FSM_FINISH;
1847 }
1848
1849 /* Error occurred.  Send error to remote host */
1850
1851 SILC_FSM_STATE(silc_ske_st_initiator_error)
1852 {
1853   SilcSKE ske = fsm_context;
1854   SilcSKEStatus status;
1855   unsigned char data[4];
1856
1857   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1858                   silc_ske_map_status(ske->status), ske->status));
1859
1860   status = ske->status;
1861   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1862     status = SILC_SKE_STATUS_ERROR;
1863
1864   /* Send FAILURE packet */
1865   SILC_PUT32_MSB((SilcUInt32)status, data);
1866   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1867
1868   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1869   silc_schedule_task_del_by_context(ske->schedule, ske);
1870
1871   /* Call completion */
1872   silc_ske_completion(ske);
1873
1874   return SILC_FSM_FINISH;
1875 }
1876
1877 /* Failure received from remote */
1878
1879 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1880 {
1881   SilcSKE ske = fsm_context;
1882   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1883
1884   if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
1885       silc_buffer_len(&ske->packet->buffer) == 4) {
1886     SILC_GET32_MSB(error, ske->packet->buffer.data);
1887     ske->status = error;
1888     silc_packet_free(ske->packet);
1889     ske->packet = NULL;
1890   }
1891
1892   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1893                   silc_ske_map_status(ske->status), ske->status));
1894
1895   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1896   silc_schedule_task_del_by_context(ske->schedule, ske);
1897
1898   /* Call completion */
1899   silc_ske_completion(ske);
1900
1901   return SILC_FSM_FINISH;
1902 }
1903
1904 /* Starts the protocol as initiator */
1905
1906 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
1907                                       SilcPacketStream stream,
1908                                       SilcSKEParams params,
1909                                       SilcSKEStartPayload start_payload)
1910 {
1911   SILC_LOG_DEBUG(("Start SKE as initiator"));
1912
1913   if (!ske || !stream || !params || !params->version)
1914     return NULL;
1915
1916   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1917     return NULL;
1918
1919   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
1920     return NULL;
1921
1922   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1923     ske->session_port = params->session_port;
1924
1925   /* Generate security properties if not provided */
1926   if (!start_payload) {
1927     start_payload = silc_ske_assemble_security_properties(ske,
1928                                                           params->flags,
1929                                                           params->version);
1930     if (!start_payload)
1931       return NULL;
1932   }
1933
1934   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
1935   ske->start_payload = start_payload;
1936   ske->version = params->version;
1937   ske->running = TRUE;
1938
1939   /* Link to packet stream to get key exchange packets */
1940   ske->stream = stream;
1941   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1942                           SILC_PACKET_KEY_EXCHANGE,
1943                           SILC_PACKET_KEY_EXCHANGE_2,
1944                           SILC_PACKET_SUCCESS,
1945                           SILC_PACKET_FAILURE, -1);
1946
1947   /* Start SKE as initiator */
1948   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1949
1950   return &ske->op;
1951 }
1952
1953 /******************************** Responder *********************************/
1954
1955 /* Start protocol as responder.  Wait initiator's start payload */
1956
1957 SILC_FSM_STATE(silc_ske_st_responder_start)
1958 {
1959   SilcSKE ske = fsm_context;
1960
1961   SILC_LOG_DEBUG(("Start"));
1962
1963   if (ske->aborted) {
1964     /** Aborted */
1965     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1966     return SILC_FSM_CONTINUE;
1967   }
1968
1969   /* Add key exchange timeout */
1970   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
1971                                  ske, ske->timeout, 0);
1972
1973   /** Wait for initiator */
1974   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1975   return SILC_FSM_WAIT;
1976 }
1977
1978 /* Decode initiator's start payload.  Select the security properties from
1979    the initiator's start payload and send our reply start payload back. */
1980
1981 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1982 {
1983   SilcSKE ske = fsm_context;
1984   SilcSKEStatus status;
1985   SilcSKEStartPayload remote_payload = NULL;
1986   SilcBuffer packet_buf = &ske->packet->buffer;
1987   SilcID id;
1988
1989   SILC_LOG_DEBUG(("Start"));
1990
1991   /* Decode the payload */
1992   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1993   if (status != SILC_SKE_STATUS_OK) {
1994     /** Error decoding Start Payload */
1995     silc_packet_free(ske->packet);
1996     ske->packet = NULL;
1997     ske->status = status;
1998     silc_fsm_next(fsm, silc_ske_st_responder_error);
1999     return SILC_FSM_CONTINUE;
2000   }
2001
2002   /* Get remote ID and set it to stream */
2003   if (ske->packet->src_id_len) {
2004     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
2005                    ske->packet->src_id_type,
2006                    (ske->packet->src_id_type == SILC_ID_SERVER ?
2007                     (void *)&id.u.server_id : (void *)&id.u.client_id),
2008                    (ske->packet->src_id_type == SILC_ID_SERVER ?
2009                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
2010     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
2011                         (ske->packet->src_id_type == SILC_ID_SERVER ?
2012                          (void *)&id.u.server_id : (void *)&id.u.client_id));
2013   }
2014
2015   /* Take a copy of the payload buffer for future use. It is used to
2016      compute the HASH value. */
2017   ske->start_payload_copy = silc_buffer_copy(packet_buf);
2018
2019   silc_packet_free(ske->packet);
2020   ske->packet = NULL;
2021
2022   /* Force the mutual authentication flag if we want to do it. */
2023   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2024     SILC_LOG_DEBUG(("Force mutual authentication"));
2025     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
2026   }
2027
2028   /* Force PFS flag if we require it */
2029   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
2030     SILC_LOG_DEBUG(("Force PFS"));
2031     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
2032   }
2033
2034   /* Disable IV Included flag if requested */
2035   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
2036       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
2037     SILC_LOG_DEBUG(("We do not support IV Included flag"));
2038     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
2039   }
2040
2041   /* Check and select security properties */
2042   status = silc_ske_select_security_properties(ske, remote_payload,
2043                                                &ske->prop);
2044   if (status != SILC_SKE_STATUS_OK) {
2045     /** Error selecting proposal */
2046     silc_ske_payload_start_free(remote_payload);
2047     ske->status = status;
2048     silc_fsm_next(fsm, silc_ske_st_responder_error);
2049     return SILC_FSM_CONTINUE;
2050   }
2051
2052   silc_ske_payload_start_free(remote_payload);
2053
2054   /* Encode our reply payload to send the selected security properties */
2055   status = silc_ske_payload_start_encode(ske, ske->start_payload,
2056                                          &packet_buf);
2057   if (status != SILC_SKE_STATUS_OK)
2058     goto err;
2059
2060   /* Send the packet. */
2061   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
2062                             silc_buffer_data(packet_buf),
2063                             silc_buffer_len(packet_buf)))
2064     goto err;
2065
2066   silc_buffer_free(packet_buf);
2067
2068   /** Waiting initiator's KE payload */
2069   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2070   return SILC_FSM_WAIT;
2071
2072  err:
2073   if (ske->prop->group)
2074     silc_ske_group_free(ske->prop->group);
2075   if (ske->prop->cipher)
2076     silc_cipher_free(ske->prop->cipher);
2077   if (ske->prop->hash)
2078     silc_hash_free(ske->prop->hash);
2079   if (ske->prop->hmac)
2080     silc_hmac_free(ske->prop->hmac);
2081   silc_free(ske->prop);
2082   ske->prop = NULL;
2083
2084   if (status == SILC_SKE_STATUS_OK)
2085     status = SILC_SKE_STATUS_ERROR;
2086
2087   /** Error */
2088   ske->status = status;
2089   silc_fsm_next(fsm, silc_ske_st_responder_error);
2090   return SILC_FSM_CONTINUE;
2091 }
2092
2093 /* Phase-2.  Decode initiator's KE payload */
2094
2095 SILC_FSM_STATE(silc_ske_st_responder_phase2)
2096 {
2097   SilcSKE ske = fsm_context;
2098   SilcSKEStatus status;
2099   SilcSKEKEPayload recv_payload;
2100   SilcBuffer packet_buf = &ske->packet->buffer;
2101
2102   SILC_LOG_DEBUG(("Start"));
2103
2104   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
2105     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2106     silc_ske_install_retransmission(ske);
2107     silc_packet_free(ske->packet);
2108     ske->packet = NULL;
2109     return SILC_FSM_WAIT;
2110   }
2111
2112   /* Decode Key Exchange Payload */
2113   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
2114   if (status != SILC_SKE_STATUS_OK) {
2115     /** Error decoding KE payload */
2116     silc_packet_free(ske->packet);
2117     ske->packet = NULL;
2118     ske->status = status;
2119     silc_fsm_next(fsm, silc_ske_st_responder_error);
2120     return SILC_FSM_CONTINUE;
2121   }
2122
2123   ske->ke1_payload = recv_payload;
2124
2125   silc_packet_free(ske->packet);
2126   ske->packet = NULL;
2127
2128   /* Verify the received public key and verify the signature if we are
2129      doing mutual authentication. */
2130   if (ske->start_payload &&
2131       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2132
2133     SILC_LOG_DEBUG(("We are doing mutual authentication"));
2134
2135     if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
2136                                    ske->repository)) {
2137       /** Public key not provided */
2138       SILC_LOG_ERROR(("Remote end did not send its public key (or "
2139                       "certificate), even though we require it"));
2140       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
2141       silc_fsm_next(fsm, silc_ske_st_responder_error);
2142       return SILC_FSM_CONTINUE;
2143     }
2144
2145     /* Decode the remote's public key */
2146     if (recv_payload->pk_data &&
2147         !silc_pkcs_public_key_alloc(recv_payload->pk_type,
2148                                     recv_payload->pk_data,
2149                                     recv_payload->pk_len,
2150                                     &ske->prop->public_key)) {
2151       /** Error decoding public key */
2152       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
2153       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
2154       silc_fsm_next(fsm, silc_ske_st_responder_error);
2155       return SILC_FSM_CONTINUE;
2156     }
2157
2158     if (ske->prop->public_key && (ske->callbacks->verify_key ||
2159                                   ske->repository)) {
2160       SILC_LOG_DEBUG(("Verifying public key"));
2161
2162       /** Waiting public key verification */
2163       silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2164
2165       /* If repository is provided, verify the key from there. */
2166       if (ske->repository) {
2167         SilcSKRFind find;
2168
2169         find = silc_skr_find_alloc();
2170         if (!find) {
2171           ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2172           silc_fsm_next(fsm, silc_ske_st_responder_error);
2173           return SILC_FSM_CONTINUE;
2174         }
2175         silc_skr_find_set_pkcs_type(find,
2176                                     silc_pkcs_get_type(ske->prop->public_key));
2177         silc_skr_find_set_public_key(find, ske->prop->public_key);
2178         silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2179
2180         /* Find key from repository */
2181         SILC_FSM_CALL(silc_skr_find(ske->repository,
2182                                     silc_fsm_get_schedule(fsm), find,
2183                                     silc_ske_skr_callback, ske));
2184       } else {
2185         /* Verify from application */
2186         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2187                                                  ske->callbacks->context,
2188                                                  silc_ske_pk_verified, NULL));
2189       }
2190       /* NOT REACHED */
2191     }
2192   }
2193
2194   /** Generate KE2 payload */
2195   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2196   return SILC_FSM_CONTINUE;
2197 }
2198
2199 /* Phase-4. Generate KE2 payload, verify signature */
2200
2201 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2202 {
2203   SilcSKE ske = fsm_context;
2204   SilcSKEStatus status;
2205   SilcSKEKEPayload recv_payload;
2206
2207   if (ske->aborted) {
2208     /** Aborted */
2209     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2210     return SILC_FSM_CONTINUE;
2211   }
2212
2213   /* Check result of public key verification */
2214   if (ske->status != SILC_SKE_STATUS_OK) {
2215     /** Public key not verified */
2216     SILC_LOG_DEBUG(("Public key verification failed"));
2217     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2218     return SILC_FSM_CONTINUE;
2219   }
2220
2221   recv_payload = ske->ke1_payload;
2222
2223   /** Send KE2 packet */
2224   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2225
2226   /* The public key verification was performed only if the Mutual
2227      Authentication flag is set. */
2228   if (ske->start_payload &&
2229       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2230     unsigned char hash[SILC_HASH_MAXLEN];
2231     SilcUInt32 hash_len;
2232
2233     SILC_LOG_DEBUG(("Public key is authentic"));
2234
2235     /* Compute the hash value */
2236     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2237     if (status != SILC_SKE_STATUS_OK) {
2238       /** Error computing hash */
2239       ske->status = status;
2240       silc_fsm_next(fsm, silc_ske_st_responder_error);
2241       return SILC_FSM_CONTINUE;
2242     }
2243
2244     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2245
2246     /* Verify signature */
2247     SILC_FSM_CALL(ske->key_op =
2248                   silc_pkcs_verify(ske->prop->public_key,
2249                                    recv_payload->sign_data,
2250                                    recv_payload->sign_len,
2251                                    hash, hash_len, NULL,
2252                                    silc_ske_verify_cb, ske));
2253     /* NOT REACHED */
2254   }
2255
2256   return SILC_FSM_CONTINUE;
2257 }
2258
2259 /* Phase-5.  Send KE2 payload */
2260
2261 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2262 {
2263   SilcSKE ske = fsm_context;
2264   SilcSKEStatus status;
2265   unsigned char hash[SILC_HASH_MAXLEN], *pk;
2266   SilcUInt32 hash_len, pk_len;
2267   SilcMPInt *x, *KEY;
2268   SilcSKEKEPayload send_payload;
2269
2270   SILC_LOG_DEBUG(("Start"));
2271
2272   /* Create the random number x, 1 < x < q. */
2273   x = silc_calloc(1, sizeof(*x));
2274   silc_mp_init(x);
2275   status =
2276     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2277                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2278                         x);
2279   if (status != SILC_SKE_STATUS_OK) {
2280     /** Error generating random number */
2281     silc_mp_uninit(x);
2282     silc_free(x);
2283     ske->status = status;
2284     silc_fsm_next(fsm, silc_ske_st_responder_error);
2285     return SILC_FSM_CONTINUE;
2286   }
2287
2288   /* Save the results for later processing */
2289   send_payload = silc_calloc(1, sizeof(*send_payload));
2290   ske->x = x;
2291   ske->ke2_payload = send_payload;
2292
2293   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2294
2295   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2296   silc_mp_init(&send_payload->x);
2297   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2298                   &ske->prop->group->group);
2299
2300   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2301
2302   /* Compute the shared secret key */
2303   KEY = silc_calloc(1, sizeof(*KEY));
2304   silc_mp_init(KEY);
2305   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2306                   &ske->prop->group->group);
2307   ske->KEY = KEY;
2308
2309   if (ske->public_key && ske->private_key) {
2310     SILC_LOG_DEBUG(("Getting public key"));
2311
2312     /* Get the public key */
2313     pk = silc_pkcs_public_key_encode(NULL, ske->public_key, &pk_len);
2314     if (!pk) {
2315       /** Error encoding public key */
2316       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2317       silc_fsm_next(fsm, silc_ske_st_responder_error);
2318       return SILC_FSM_CONTINUE;
2319     }
2320     ske->ke2_payload->pk_data = pk;
2321     ske->ke2_payload->pk_len = pk_len;
2322   }
2323
2324   SILC_LOG_DEBUG(("Computing HASH value"));
2325
2326   /* Compute the hash value */
2327   memset(hash, 0, sizeof(hash));
2328   status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2329   if (status != SILC_SKE_STATUS_OK) {
2330     /** Error computing hash */
2331     ske->status = status;
2332     silc_fsm_next(fsm, silc_ske_st_responder_error);
2333     return SILC_FSM_CONTINUE;
2334   }
2335   ske->hash = silc_memdup(hash, hash_len);
2336   ske->hash_len = hash_len;
2337
2338   /** Send KE2 packet */
2339   silc_fsm_next(fsm, silc_ske_st_responder_phase5_send);
2340
2341   if (ske->public_key && ske->private_key) {
2342     SILC_LOG_DEBUG(("Signing HASH value"));
2343
2344     /* Sign the hash value */
2345     SILC_FSM_CALL(ske->key_op =
2346                   silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
2347                                  ske->prop->hash, ske->rng,
2348                                  silc_ske_responder_sign_cb, ske));
2349     /* NOT REACHED */
2350   }
2351
2352   return SILC_FSM_CONTINUE;
2353 }
2354
2355 /* Send KE2 packet */
2356
2357 SILC_FSM_STATE(silc_ske_st_responder_phase5_send)
2358 {
2359   SilcSKE ske = fsm_context;
2360   SilcSKEStatus status;
2361   SilcBuffer payload_buf;
2362
2363   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2364
2365   /* Encode the Key Exchange Payload */
2366   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2367                                       &payload_buf);
2368   if (status != SILC_SKE_STATUS_OK) {
2369     /** Error encoding KE payload */
2370     ske->status = status;
2371     silc_fsm_next(fsm, silc_ske_st_responder_error);
2372     return SILC_FSM_CONTINUE;
2373   }
2374
2375   /* Send the packet. */
2376   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2377                             payload_buf->data, silc_buffer_len(payload_buf))) {
2378     SILC_LOG_DEBUG(("Error sending packet"));
2379     ske->status = SILC_SKE_STATUS_ERROR;
2380     silc_fsm_next(fsm, silc_ske_st_responder_error);
2381     return SILC_FSM_CONTINUE;
2382   }
2383
2384   silc_buffer_free(payload_buf);
2385
2386   /* In case we are doing rekey move to finish it. */
2387   if (ske->rekey) {
2388     /** Finish rekey */
2389     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2390     return SILC_FSM_CONTINUE;
2391   }
2392
2393   /** Waiting completion */
2394   silc_fsm_next(fsm, silc_ske_st_responder_end);
2395   return SILC_FSM_WAIT;
2396 }
2397
2398 /* Protocol completed */
2399
2400 SILC_FSM_STATE(silc_ske_st_responder_end)
2401 {
2402   SilcSKE ske = fsm_context;
2403   unsigned char tmp[4];
2404   SilcUInt32 hash_len, key_len, block_len;
2405
2406   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2407     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2408     silc_ske_install_retransmission(ske);
2409     silc_packet_free(ske->packet);
2410     ske->packet = NULL;
2411     return SILC_FSM_WAIT;
2412   }
2413   silc_packet_free(ske->packet);
2414   ske->packet = NULL;
2415
2416   /* Process key material */
2417   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2418   block_len = silc_cipher_get_block_len(ske->prop->cipher);
2419   hash_len = silc_hash_len(ske->prop->hash);
2420   ske->keymat = silc_ske_process_key_material(ske, block_len,
2421                                               key_len, hash_len,
2422                                               &ske->rekey);
2423   if (!ske->keymat) {
2424     /** Error processing key material */
2425     ske->status = SILC_SKE_STATUS_ERROR;
2426     silc_fsm_next(fsm, silc_ske_st_responder_error);
2427     return SILC_FSM_CONTINUE;
2428   }
2429
2430   /* Send SUCCESS packet */
2431   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2432   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2433
2434   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2435   silc_schedule_task_del_by_context(ske->schedule, ske);
2436
2437   /* Call completion */
2438   silc_ske_completion(ske);
2439
2440   return SILC_FSM_FINISH;
2441 }
2442
2443 /* Aborted by application */
2444
2445 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2446 {
2447   SilcSKE ske = fsm_context;
2448   unsigned char tmp[4];
2449
2450   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2451
2452   /* Send FAILURE packet */
2453   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2454   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2455
2456   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2457   silc_schedule_task_del_by_context(ske->schedule, ske);
2458
2459   /* Call completion */
2460   silc_ske_completion(ske);
2461
2462   return SILC_FSM_FINISH;
2463 }
2464
2465 /* Failure received from remote */
2466
2467 SILC_FSM_STATE(silc_ske_st_responder_failure)
2468 {
2469   SilcSKE ske = fsm_context;
2470   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2471
2472   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2473
2474   if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
2475       silc_buffer_len(&ske->packet->buffer) == 4) {
2476     SILC_GET32_MSB(error, ske->packet->buffer.data);
2477     ske->status = error;
2478     silc_packet_free(ske->packet);
2479     ske->packet = NULL;
2480   }
2481
2482   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2483   silc_schedule_task_del_by_context(ske->schedule, ske);
2484
2485   /* Call completion */
2486   silc_ske_completion(ske);
2487
2488   return SILC_FSM_FINISH;
2489 }
2490
2491 /* Error occurred */
2492
2493 SILC_FSM_STATE(silc_ske_st_responder_error)
2494 {
2495   SilcSKE ske = fsm_context;
2496   unsigned char tmp[4];
2497
2498   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2499                   ske->status, silc_ske_map_status(ske->status)));
2500
2501   /* Send FAILURE packet */
2502   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2503     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2504   SILC_PUT32_MSB(ske->status, tmp);
2505   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2506
2507   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2508   silc_schedule_task_del_by_context(ske->schedule, ske);
2509
2510   /* Call completion */
2511   silc_ske_completion(ske);
2512
2513   return SILC_FSM_FINISH;
2514 }
2515
2516 /* Starts the protocol as responder. */
2517
2518 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
2519                                       SilcPacketStream stream,
2520                                       SilcSKEParams params)
2521 {
2522   SILC_LOG_DEBUG(("Start SKE as responder"));
2523
2524   if (!ske || !stream || !params || !params->version)
2525     return NULL;
2526
2527   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2528     return NULL;
2529
2530   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2531     return NULL;
2532
2533   ske->responder = TRUE;
2534   ske->flags = params->flags;
2535   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
2536   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2537     ske->session_port = params->session_port;
2538   ske->version = strdup(params->version);
2539   if (!ske->version)
2540     return NULL;
2541   ske->running = TRUE;
2542
2543   /* Link to packet stream to get key exchange packets */
2544   ske->stream = stream;
2545   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2546                           SILC_PACKET_KEY_EXCHANGE,
2547                           SILC_PACKET_KEY_EXCHANGE_1,
2548                           SILC_PACKET_SUCCESS,
2549                           SILC_PACKET_FAILURE, -1);
2550
2551   /* Start SKE as responder */
2552   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2553
2554   return &ske->op;
2555 }
2556
2557 /***************************** Initiator Rekey ******************************/
2558
2559 /* Start rekey */
2560
2561 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2562 {
2563   SilcSKE ske = fsm_context;
2564   SilcStatus status;
2565
2566   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2567
2568   if (ske->aborted) {
2569     /** Aborted */
2570     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
2571     return SILC_FSM_CONTINUE;
2572   }
2573
2574   /* Add rekey exchange timeout */
2575   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2576                                  ske, 30, 0);
2577
2578   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2579   if (!ske->prop) {
2580     /** No memory */
2581     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2582     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2583     return SILC_FSM_CONTINUE;
2584   }
2585
2586   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2587     /** Cannot allocate hash */
2588     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2589     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2590     return SILC_FSM_CONTINUE;
2591   }
2592
2593   /* Send REKEY packet to start rekey protocol */
2594   if (!silc_ske_packet_send(ske, SILC_PACKET_REKEY, 0, NULL, 0)) {
2595     /** Error sending packet */
2596     SILC_LOG_DEBUG(("Error sending packet"));
2597     ske->status = SILC_SKE_STATUS_ERROR;
2598     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2599     return SILC_FSM_CONTINUE;
2600   }
2601
2602   /* If doing rekey without PFS, move directly to the end of the protocol. */
2603   if (!ske->rekey->pfs) {
2604     /** Rekey without PFS */
2605     silc_fsm_next(fsm, silc_ske_st_rekey_initiator_done);
2606     return SILC_FSM_CONTINUE;
2607   }
2608
2609   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2610                                         &ske->prop->group);
2611   if (status != SILC_SKE_STATUS_OK) {
2612     /** Unknown group */
2613     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2614     return SILC_FSM_CONTINUE;
2615   }
2616
2617   /** Rekey with PFS */
2618   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
2619   return SILC_FSM_CONTINUE;
2620 }
2621
2622 /* Sends REKEY_DONE packet to finish the protocol. */
2623
2624 SILC_FSM_STATE(silc_ske_st_rekey_initiator_done)
2625 {
2626   SilcSKE ske = fsm_context;
2627   SilcCipher send_key;
2628   SilcHmac hmac_send;
2629   SilcHash hash;
2630   SilcUInt32 key_len, block_len, hash_len, x_len;
2631   unsigned char *pfsbuf;
2632
2633   SILC_LOG_DEBUG(("Start"));
2634
2635   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2636   key_len = silc_cipher_get_key_len(send_key);
2637   block_len = silc_cipher_get_block_len(send_key);
2638   hash = ske->prop->hash;
2639   hash_len = silc_hash_len(hash);
2640
2641   /* Process key material */
2642   if (ske->rekey->pfs) {
2643     /* PFS */
2644     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2645     if (pfsbuf) {
2646       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2647                                                        block_len, key_len,
2648                                                        hash_len, hash);
2649       memset(pfsbuf, 0, x_len);
2650       silc_free(pfsbuf);
2651     }
2652   } else {
2653     /* No PFS */
2654     ske->keymat =
2655       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2656                                          ske->rekey->enc_key_len / 8,
2657                                          block_len, key_len,
2658                                          hash_len, hash);
2659   }
2660
2661   if (!ske->keymat) {
2662     SILC_LOG_ERROR(("Error processing key material"));
2663     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2664     return SILC_FSM_CONTINUE;
2665   }
2666
2667   ske->prop->cipher = send_key;
2668   ske->prop->hmac = hmac_send;
2669
2670   /* Get sending keys */
2671   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2672                          &hmac_send, NULL, NULL)) {
2673     /** Cannot get keys */
2674     ske->status = SILC_SKE_STATUS_ERROR;
2675     ske->prop->cipher = NULL;
2676     ske->prop->hmac = NULL;
2677     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2678     return SILC_FSM_CONTINUE;
2679   }
2680
2681   ske->prop->cipher = NULL;
2682   ske->prop->hmac = NULL;
2683
2684   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2685      packet sent after this call will be protected with the new keys. */
2686   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2687                             TRUE)) {
2688     /** Cannot set keys */
2689     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2690     ske->status = SILC_SKE_STATUS_ERROR;
2691     silc_cipher_free(send_key);
2692     silc_hmac_free(hmac_send);
2693     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2694     return SILC_FSM_CONTINUE;
2695   }
2696
2697   /** Wait for REKEY_DONE */
2698   silc_fsm_next(fsm, silc_ske_st_rekey_initiator_end);
2699   return SILC_FSM_WAIT;
2700 }
2701
2702 /* Rekey protocol end */
2703
2704 SILC_FSM_STATE(silc_ske_st_rekey_initiator_end)
2705 {
2706   SilcSKE ske = fsm_context;
2707   SilcCipher receive_key;
2708   SilcHmac hmac_receive;
2709   SilcSKERekeyMaterial rekey;
2710
2711   SILC_LOG_DEBUG(("Start"));
2712
2713   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2714     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2715     silc_packet_free(ske->packet);
2716     ske->packet = NULL;
2717     return SILC_FSM_WAIT;
2718   }
2719
2720   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2721   ske->prop->cipher = receive_key;
2722   ske->prop->hmac = hmac_receive;
2723
2724   /* Get receiving keys */
2725   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
2726                          NULL, &hmac_receive, NULL)) {
2727     /** Cannot get keys */
2728     ske->status = SILC_SKE_STATUS_ERROR;
2729     ske->prop->cipher = NULL;
2730     ske->prop->hmac = NULL;
2731     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2732     return SILC_FSM_CONTINUE;
2733   }
2734
2735   /* Set new receiving keys into use.  All packets received after this will
2736      be decrypted with the new keys. */
2737   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
2738                             hmac_receive, FALSE)) {
2739     /** Cannot set keys */
2740     SILC_LOG_DEBUG(("Cannot set new keys"));
2741     ske->status = SILC_SKE_STATUS_ERROR;
2742     silc_cipher_free(receive_key);
2743     silc_hmac_free(hmac_receive);
2744     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2745     return SILC_FSM_CONTINUE;
2746   }
2747
2748   SILC_LOG_DEBUG(("Rekey completed successfully"));
2749
2750   /* Generate new rekey material */
2751   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
2752   if (!rekey) {
2753     /** No memory */
2754     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2755     ske->prop->cipher = NULL;
2756     ske->prop->hmac = NULL;
2757     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2758     return SILC_FSM_CONTINUE;
2759   }
2760   rekey->pfs = ske->rekey->pfs;
2761   ske->rekey = rekey;
2762
2763   ske->prop->cipher = NULL;
2764   ske->prop->hmac = NULL;
2765   silc_packet_free(ske->packet);
2766   ske->packet = NULL;
2767   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2768   silc_schedule_task_del_by_context(ske->schedule, ske);
2769
2770   /* Call completion */
2771   silc_ske_completion(ske);
2772
2773   return SILC_FSM_FINISH;
2774 }
2775
2776 /* Starts rekey protocol as initiator */
2777
2778 SilcAsyncOperation
2779 silc_ske_rekey_initiator(SilcSKE ske,
2780                          SilcPacketStream stream,
2781                          SilcSKERekeyMaterial rekey)
2782 {
2783   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2784
2785   if (!ske || !stream || !rekey) {
2786     SILC_LOG_ERROR(("Missing arguments to silc_ske_rekey_initiator"));
2787     SILC_ASSERT(rekey);
2788     return NULL;
2789   }
2790
2791   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2792     return NULL;
2793
2794   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
2795     return NULL;
2796
2797   ske->rekey = rekey;
2798   ske->responder = FALSE;
2799   ske->running = TRUE;
2800   ske->rekeying = TRUE;
2801
2802   /* Link to packet stream to get key exchange packets */
2803   ske->stream = stream;
2804   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2805                           SILC_PACKET_REKEY,
2806                           SILC_PACKET_REKEY_DONE,
2807                           SILC_PACKET_KEY_EXCHANGE_2,
2808                           SILC_PACKET_SUCCESS,
2809                           SILC_PACKET_FAILURE, -1);
2810
2811   /* Start SKE rekey as initiator */
2812   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2813
2814   return &ske->op;
2815 }
2816
2817 /***************************** Responder Rekey ******************************/
2818
2819 /* Wait for initiator's packet */
2820
2821 SILC_FSM_STATE(silc_ske_st_rekey_responder_wait)
2822 {
2823   SilcSKE ske = fsm_context;
2824
2825   SILC_LOG_DEBUG(("Start rekey (%s)", ske->rekey->pfs ? "PFS" : "No PFS"));
2826
2827   if (ske->aborted) {
2828     /** Aborted */
2829     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2830     return SILC_FSM_CONTINUE;
2831   }
2832
2833   /* Add rekey exchange timeout */
2834   silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
2835                                  ske, 30, 0);
2836
2837   silc_fsm_next(fsm, silc_ske_st_rekey_responder_start);
2838
2839   /* If REKEY packet already received process it directly */
2840   if (ske->packet && ske->packet->type == SILC_PACKET_REKEY)
2841     return SILC_FSM_CONTINUE;
2842
2843   /* Wait for REKEY */
2844   return SILC_FSM_WAIT;
2845 }
2846
2847 /* Process initiator's REKEY packet */
2848
2849 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2850 {
2851   SilcSKE ske = fsm_context;
2852   SilcSKEStatus status;
2853
2854   SILC_LOG_DEBUG(("Start"));
2855
2856   if (ske->packet->type != SILC_PACKET_REKEY) {
2857     ske->status = SILC_SKE_STATUS_ERROR;
2858     silc_packet_free(ske->packet);
2859     ske->packet = NULL;
2860     silc_fsm_next(fsm, silc_ske_st_responder_error);
2861     return SILC_FSM_CONTINUE;
2862   }
2863
2864   ske->prop = silc_calloc(1, sizeof(*ske->prop));
2865   if (!ske->prop) {
2866     /** No memory */
2867     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2868     silc_fsm_next(fsm, silc_ske_st_responder_error);
2869     return SILC_FSM_CONTINUE;
2870   }
2871
2872   if (!silc_hash_alloc(ske->rekey->hash, &ske->prop->hash)) {
2873     /** Cannot allocate hash */
2874     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2875     silc_fsm_next(fsm, silc_ske_st_responder_error);
2876     return SILC_FSM_CONTINUE;
2877   }
2878
2879   /* If doing rekey without PFS, move directly to the end of the protocol. */
2880   if (!ske->rekey->pfs) {
2881     /** Rekey without PFS */
2882     silc_fsm_next(fsm, silc_ske_st_rekey_responder_done);
2883     return SILC_FSM_CONTINUE;
2884   }
2885
2886   status = silc_ske_group_get_by_number(ske->rekey->ske_group,
2887                                         &ske->prop->group);
2888   if (status != SILC_SKE_STATUS_OK) {
2889     /** Unknown group */
2890     silc_fsm_next(fsm, silc_ske_st_responder_error);
2891     return SILC_FSM_CONTINUE;
2892   }
2893
2894   /** Rekey with PFS */
2895   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
2896   return SILC_FSM_WAIT;
2897 }
2898
2899 /* Sends REKEY_DONE packet to finish the protocol. */
2900
2901 SILC_FSM_STATE(silc_ske_st_rekey_responder_done)
2902 {
2903   SilcSKE ske = fsm_context;
2904   SilcCipher send_key;
2905   SilcHmac hmac_send;
2906   SilcHash hash;
2907   SilcUInt32 key_len, block_len, hash_len, x_len;
2908   unsigned char *pfsbuf;
2909
2910   SILC_LOG_DEBUG(("Start"));
2911
2912   silc_packet_get_keys(ske->stream, &send_key, NULL, &hmac_send, NULL);
2913   key_len = silc_cipher_get_key_len(send_key);
2914   block_len = silc_cipher_get_block_len(send_key);
2915   hash = ske->prop->hash;
2916   hash_len = silc_hash_len(hash);
2917
2918   /* Process key material */
2919   if (ske->rekey->pfs) {
2920     /* PFS */
2921     pfsbuf = silc_mp_mp2bin(ske->KEY, 0, &x_len);
2922     if (pfsbuf) {
2923       ske->keymat = silc_ske_process_key_material_data(pfsbuf, x_len,
2924                                                        block_len, key_len,
2925                                                        hash_len, hash);
2926       memset(pfsbuf, 0, x_len);
2927       silc_free(pfsbuf);
2928     }
2929   } else {
2930     /* No PFS */
2931     ske->keymat =
2932       silc_ske_process_key_material_data(ske->rekey->send_enc_key,
2933                                          ske->rekey->enc_key_len / 8,
2934                                          block_len, key_len,
2935                                          hash_len, hash);
2936   }
2937
2938   if (!ske->keymat) {
2939     SILC_LOG_ERROR(("Error processing key material"));
2940     silc_fsm_next(fsm, silc_ske_st_responder_error);
2941     return SILC_FSM_CONTINUE;
2942   }
2943
2944   ske->prop->cipher = send_key;
2945   ske->prop->hmac = hmac_send;
2946
2947   /* Get sending keys */
2948   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, &send_key, NULL,
2949                          &hmac_send, NULL, NULL)) {
2950     /** Cannot get keys */
2951     ske->status = SILC_SKE_STATUS_ERROR;
2952     ske->prop->cipher = NULL;
2953     ske->prop->hmac = NULL;
2954     silc_fsm_next(fsm, silc_ske_st_responder_error);
2955     return SILC_FSM_CONTINUE;
2956   }
2957
2958   ske->prop->cipher = NULL;
2959   ske->prop->hmac = NULL;
2960
2961   /* Set the new keys into use.  This will also send REKEY_DONE packet.  Any
2962      packet sent after this call will be protected with the new keys. */
2963   if (!silc_packet_set_keys(ske->stream, send_key, NULL, hmac_send, NULL,
2964                             TRUE)) {
2965     /** Cannot set keys */
2966     SILC_LOG_DEBUG(("Cannot set new keys, error sending REKEY_DONE"));
2967     ske->status = SILC_SKE_STATUS_ERROR;
2968     silc_cipher_free(send_key);
2969     silc_hmac_free(hmac_send);
2970     silc_fsm_next(fsm, silc_ske_st_responder_error);
2971     return SILC_FSM_CONTINUE;
2972   }
2973
2974   /** Wait for REKEY_DONE */
2975   silc_fsm_next(fsm, silc_ske_st_rekey_responder_end);
2976   return SILC_FSM_WAIT;
2977 }
2978
2979 /* Rekey protocol end */
2980
2981 SILC_FSM_STATE(silc_ske_st_rekey_responder_end)
2982 {
2983   SilcSKE ske = fsm_context;
2984   SilcCipher receive_key;
2985   SilcHmac hmac_receive;
2986   SilcSKERekeyMaterial rekey;
2987
2988   SILC_LOG_DEBUG(("Start"));
2989
2990   if (ske->packet->type != SILC_PACKET_REKEY_DONE) {
2991     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2992     silc_packet_free(ske->packet);
2993     ske->packet = NULL;
2994     return SILC_FSM_WAIT;
2995   }
2996
2997   silc_packet_get_keys(ske->stream, NULL, &receive_key, NULL, &hmac_receive);
2998   ske->prop->cipher = receive_key;
2999   ske->prop->hmac = hmac_receive;
3000
3001   /* Get receiving keys */
3002   if (!silc_ske_set_keys(ske, ske->keymat, ske->prop, NULL, &receive_key,
3003                          NULL, &hmac_receive, NULL)) {
3004     /** Cannot get keys */
3005     ske->status = SILC_SKE_STATUS_ERROR;
3006     ske->prop->cipher = NULL;
3007     ske->prop->hmac = NULL;
3008     silc_fsm_next(fsm, silc_ske_st_responder_error);
3009     return SILC_FSM_CONTINUE;
3010   }
3011
3012   /* Set new receiving keys into use.  All packets received after this will
3013      be decrypted with the new keys. */
3014   if (!silc_packet_set_keys(ske->stream, NULL, receive_key, NULL,
3015                             hmac_receive, FALSE)) {
3016     /** Cannot set keys */
3017     SILC_LOG_DEBUG(("Cannot set new keys"));
3018     ske->status = SILC_SKE_STATUS_ERROR;
3019     ske->prop->cipher = NULL;
3020     ske->prop->hmac = NULL;
3021     silc_cipher_free(receive_key);
3022     silc_hmac_free(hmac_receive);
3023     silc_fsm_next(fsm, silc_ske_st_responder_error);
3024     return SILC_FSM_CONTINUE;
3025   }
3026
3027   SILC_LOG_DEBUG(("Rekey completed successfully"));
3028
3029   /* Generate new rekey material */
3030   rekey = silc_ske_make_rekey_material(ske, ske->keymat);
3031   if (!rekey) {
3032     /** No memory */
3033     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
3034     ske->prop->cipher = NULL;
3035     ske->prop->hmac = NULL;
3036     silc_fsm_next(fsm, silc_ske_st_responder_error);
3037     return SILC_FSM_CONTINUE;
3038   }
3039   rekey->pfs = ske->rekey->pfs;
3040   ske->rekey = rekey;
3041
3042   ske->prop->cipher = NULL;
3043   ske->prop->hmac = NULL;
3044   silc_packet_free(ske->packet);
3045   ske->packet = NULL;
3046   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
3047   silc_schedule_task_del_by_context(ske->schedule, ske);
3048
3049   /* Call completion */
3050   silc_ske_completion(ske);
3051
3052   return SILC_FSM_FINISH;
3053 }
3054
3055 /* Starts rekey protocol as responder */
3056
3057 SilcAsyncOperation
3058 silc_ske_rekey_responder(SilcSKE ske,
3059                          SilcPacketStream stream,
3060                          SilcSKERekeyMaterial rekey,
3061                          SilcPacket packet)
3062 {
3063   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
3064
3065   if (!ske || !stream || !rekey)
3066     return NULL;
3067
3068   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
3069     return NULL;
3070
3071   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_finished, ske, ske->schedule))
3072     return NULL;
3073
3074   ske->rekey = rekey;
3075   ske->responder = TRUE;
3076   ske->running = TRUE;
3077   ske->rekeying = TRUE;
3078   ske->packet = packet;
3079
3080   /* Link to packet stream to get key exchange packets */
3081   ske->stream = stream;
3082   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
3083                           SILC_PACKET_REKEY,
3084                           SILC_PACKET_REKEY_DONE,
3085                           SILC_PACKET_KEY_EXCHANGE_1,
3086                           SILC_PACKET_SUCCESS,
3087                           SILC_PACKET_FAILURE, -1);
3088
3089   /* Start SKE rekey as responder */
3090   silc_fsm_start_sync(&ske->fsm, silc_ske_st_rekey_responder_wait);
3091
3092   return &ske->op;
3093 }
3094
3095 /* Processes the provided key material `data' as the SILC protocol
3096    specification defines. */
3097
3098 SilcSKEKeyMaterial
3099 silc_ske_process_key_material_data(unsigned char *data,
3100                                    SilcUInt32 data_len,
3101                                    SilcUInt32 req_iv_len,
3102                                    SilcUInt32 req_enc_key_len,
3103                                    SilcUInt32 req_hmac_key_len,
3104                                    SilcHash hash)
3105 {
3106   SilcBuffer buf;
3107   unsigned char hashd[SILC_HASH_MAXLEN];
3108   SilcUInt32 hash_len = req_hmac_key_len;
3109   SilcUInt32 enc_key_len = req_enc_key_len / 8;
3110   SilcSKEKeyMaterial key;
3111
3112   SILC_LOG_DEBUG(("Start"));
3113
3114   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
3115     return NULL;
3116
3117   key = silc_calloc(1, sizeof(*key));
3118   if (!key)
3119     return NULL;
3120
3121   buf = silc_buffer_alloc_size(1 + data_len);
3122   if (!buf)
3123     return NULL;
3124   silc_buffer_format(buf,
3125                      SILC_STR_UI_CHAR(0),
3126                      SILC_STR_DATA(data, data_len),
3127                      SILC_STR_END);
3128
3129   /* Take IVs */
3130   memset(hashd, 0, sizeof(hashd));
3131   buf->data[0] = 0;
3132   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3133   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3134   memcpy(key->send_iv, hashd, req_iv_len);
3135   memset(hashd, 0, sizeof(hashd));
3136   buf->data[0] = 1;
3137   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3138   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
3139   memcpy(key->receive_iv, hashd, req_iv_len);
3140   key->iv_len = req_iv_len;
3141
3142   /* Take the encryption keys. If requested key size is more than
3143      the size of hash length we will distribute more key material
3144      as protocol defines. */
3145   buf->data[0] = 2;
3146   if (enc_key_len > hash_len) {
3147     SilcBuffer dist;
3148     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3149         k3[SILC_HASH_MAXLEN];
3150     unsigned char *dtmp;
3151
3152     /* XXX */
3153     if (enc_key_len > (3 * hash_len))
3154       return NULL;
3155
3156     /* Take first round */
3157     memset(k1, 0, sizeof(k1));
3158     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3159
3160     /* Take second round */
3161     dist = silc_buffer_alloc_size(data_len + hash_len);
3162     if (!dist)
3163       return NULL;
3164     silc_buffer_format(dist,
3165                        SILC_STR_DATA(data, data_len),
3166                        SILC_STR_DATA(k1, hash_len),
3167                        SILC_STR_END);
3168     memset(k2, 0, sizeof(k2));
3169     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3170
3171     /* Take third round */
3172     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3173     silc_buffer_pull_tail(dist, hash_len);
3174     silc_buffer_pull(dist, data_len + hash_len);
3175     silc_buffer_format(dist,
3176                        SILC_STR_DATA(k2, hash_len),
3177                        SILC_STR_END);
3178     silc_buffer_push(dist, data_len + hash_len);
3179     memset(k3, 0, sizeof(k3));
3180     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3181
3182     /* Then, save the keys */
3183     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3184     memcpy(dtmp, k1, hash_len);
3185     memcpy(dtmp + hash_len, k2, hash_len);
3186     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3187
3188     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3189     memcpy(key->send_enc_key, dtmp, enc_key_len);
3190     key->enc_key_len = req_enc_key_len;
3191
3192     memset(dtmp, 0, (3 * hash_len));
3193     memset(k1, 0, sizeof(k1));
3194     memset(k2, 0, sizeof(k2));
3195     memset(k3, 0, sizeof(k3));
3196     silc_free(dtmp);
3197     silc_buffer_clear(dist);
3198     silc_buffer_free(dist);
3199   } else {
3200     /* Take normal hash as key */
3201     memset(hashd, 0, sizeof(hashd));
3202     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3203     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3204     memcpy(key->send_enc_key, hashd, enc_key_len);
3205     key->enc_key_len = req_enc_key_len;
3206   }
3207
3208   buf->data[0] = 3;
3209   if (enc_key_len > hash_len) {
3210     SilcBuffer dist;
3211     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
3212         k3[SILC_HASH_MAXLEN];
3213     unsigned char *dtmp;
3214
3215     /* XXX */
3216     if (enc_key_len > (3 * hash_len))
3217       return NULL;
3218
3219     /* Take first round */
3220     memset(k1, 0, sizeof(k1));
3221     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
3222
3223     /* Take second round */
3224     dist = silc_buffer_alloc_size(data_len + hash_len);
3225     if (!dist)
3226       return NULL;
3227     silc_buffer_format(dist,
3228                        SILC_STR_DATA(data, data_len),
3229                        SILC_STR_DATA(k1, hash_len),
3230                        SILC_STR_END);
3231     memset(k2, 0, sizeof(k2));
3232     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
3233
3234     /* Take third round */
3235     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
3236     silc_buffer_pull_tail(dist, hash_len);
3237     silc_buffer_pull(dist, data_len + hash_len);
3238     silc_buffer_format(dist,
3239                        SILC_STR_DATA(k2, hash_len),
3240                        SILC_STR_END);
3241     silc_buffer_push(dist, data_len + hash_len);
3242     memset(k3, 0, sizeof(k3));
3243     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
3244
3245     /* Then, save the keys */
3246     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
3247     memcpy(dtmp, k1, hash_len);
3248     memcpy(dtmp + hash_len, k2, hash_len);
3249     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
3250
3251     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3252     memcpy(key->receive_enc_key, dtmp, enc_key_len);
3253     key->enc_key_len = req_enc_key_len;
3254
3255     memset(dtmp, 0, (3 * hash_len));
3256     memset(k1, 0, sizeof(k1));
3257     memset(k2, 0, sizeof(k2));
3258     memset(k3, 0, sizeof(k3));
3259     silc_free(dtmp);
3260     silc_buffer_clear(dist);
3261     silc_buffer_free(dist);
3262   } else {
3263     /* Take normal hash as key */
3264     memset(hashd, 0, sizeof(hashd));
3265     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3266     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
3267     memcpy(key->receive_enc_key, hashd, enc_key_len);
3268     key->enc_key_len = req_enc_key_len;
3269   }
3270
3271   /* Take HMAC keys */
3272   memset(hashd, 0, sizeof(hashd));
3273   buf->data[0] = 4;
3274   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3275   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3276   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
3277   memset(hashd, 0, sizeof(hashd));
3278   buf->data[0] = 5;
3279   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
3280   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
3281   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
3282   key->hmac_key_len = req_hmac_key_len;
3283   memset(hashd, 0, sizeof(hashd));
3284
3285   silc_buffer_clear(buf);
3286   silc_buffer_free(buf);
3287
3288   SILC_LOG_HEXDUMP(("enc"), key->send_enc_key, key->enc_key_len / 8);
3289
3290   return key;
3291 }
3292
3293 /* Processes negotiated key material as protocol specifies. This returns
3294    the actual keys to be used in the SILC. */
3295
3296 SilcSKEKeyMaterial
3297 silc_ske_process_key_material(SilcSKE ske,
3298                               SilcUInt32 req_iv_len,
3299                               SilcUInt32 req_enc_key_len,
3300                               SilcUInt32 req_hmac_key_len,
3301                               SilcSKERekeyMaterial *rekey)
3302 {
3303   SilcBuffer buf;
3304   unsigned char *tmpbuf;
3305   SilcUInt32 klen;
3306   SilcSKEKeyMaterial key;
3307
3308   /* Encode KEY to binary data */
3309   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
3310
3311   buf = silc_buffer_alloc_size(klen + ske->hash_len);
3312   if (!buf)
3313     return NULL;
3314   silc_buffer_format(buf,
3315                      SILC_STR_DATA(tmpbuf, klen),
3316                      SILC_STR_DATA(ske->hash, ske->hash_len),
3317                      SILC_STR_END);
3318
3319   /* Process the key material */
3320   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
3321                                            req_iv_len, req_enc_key_len,
3322                                            req_hmac_key_len,
3323                                            ske->prop->hash);
3324
3325   memset(tmpbuf, 0, klen);
3326   silc_free(tmpbuf);
3327   silc_buffer_clear(buf);
3328   silc_buffer_free(buf);
3329
3330   if (rekey) {
3331     *rekey = silc_ske_make_rekey_material(ske, key);
3332     if (!(*rekey))
3333       return NULL;
3334   }
3335
3336   return key;
3337 }
3338
3339 /* Free key material structure */
3340
3341 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
3342 {
3343   if (!key)
3344     return;
3345
3346   if (key->send_iv)
3347     silc_free(key->send_iv);
3348   if (key->receive_iv)
3349     silc_free(key->receive_iv);
3350   if (key->send_enc_key) {
3351     memset(key->send_enc_key, 0, key->enc_key_len / 8);
3352     silc_free(key->send_enc_key);
3353   }
3354   if (key->receive_enc_key) {
3355     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
3356     silc_free(key->receive_enc_key);
3357   }
3358   if (key->send_hmac_key) {
3359     memset(key->send_hmac_key, 0, key->hmac_key_len);
3360     silc_free(key->send_hmac_key);
3361   }
3362   if (key->receive_hmac_key) {
3363     memset(key->receive_hmac_key, 0, key->hmac_key_len);
3364     silc_free(key->receive_hmac_key);
3365   }
3366   silc_free(key);
3367 }
3368
3369 /* Free rekey material */
3370
3371 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey)
3372 {
3373   if (!rekey)
3374     return;
3375   if (rekey->send_enc_key) {
3376     memset(rekey->send_enc_key, 0, rekey->enc_key_len / 8);
3377     silc_free(rekey->send_enc_key);
3378   }
3379   silc_free(rekey->hash);
3380   silc_free(rekey);
3381 }
3382
3383 /* Set keys into use */
3384
3385 SilcBool silc_ske_set_keys(SilcSKE ske,
3386                            SilcSKEKeyMaterial keymat,
3387                            SilcSKESecurityProperties prop,
3388                            SilcCipher *ret_send_key,
3389                            SilcCipher *ret_receive_key,
3390                            SilcHmac *ret_hmac_send,
3391                            SilcHmac *ret_hmac_receive,
3392                            SilcHash *ret_hash)
3393 {
3394   unsigned char iv[SILC_HASH_MAXLEN];
3395   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
3396
3397   /* Allocate ciphers to be used in the communication */
3398   if (ret_send_key) {
3399     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3400                            ret_send_key))
3401       return FALSE;
3402   }
3403   if (ret_receive_key) {
3404     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
3405                            ret_receive_key))
3406       return FALSE;
3407   }
3408
3409   /* Allocate HMACs */
3410   if (ret_hmac_send) {
3411     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3412                          ret_hmac_send))
3413       return FALSE;
3414   }
3415   if (ret_hmac_receive) {
3416     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
3417                          ret_hmac_receive))
3418       return FALSE;
3419   }
3420
3421   /* Allocate hash */
3422   if (ret_hash) {
3423     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
3424       return FALSE;
3425   }
3426
3427   /* Set key material */
3428   memset(iv, 0, sizeof(iv));
3429   if (ske->responder) {
3430     if (ret_send_key) {
3431       silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
3432                           keymat->enc_key_len, TRUE);
3433
3434       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3435         /* Counter mode */
3436         if (!ske->rekeying) {
3437           /* Set IV. */
3438           memcpy(iv, ske->hash, 4);
3439           if (!iv_included)
3440             memcpy(iv + 4, keymat->receive_iv, 8);
3441         } else {
3442           /* Rekey, recompute the truncated hash value. */
3443           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3444           if (!iv_included)
3445             memcpy(iv + 4, keymat->receive_iv, 8);
3446           else
3447             memset(iv + 4, 0, 12);
3448         }
3449
3450         silc_cipher_set_iv(*ret_send_key, iv);
3451       } else {
3452         /* Other modes */
3453         silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
3454       }
3455     }
3456     if (ret_receive_key) {
3457       silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
3458                           keymat->enc_key_len, FALSE);
3459
3460       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3461         /* Counter mode */
3462         if (!ske->rekeying) {
3463           /* Set IV. */
3464           memcpy(iv, ske->hash, 4);
3465           if (!iv_included)
3466             memcpy(iv + 4, keymat->send_iv, 8);
3467         } else {
3468           /* Rekey, recompute the truncated hash value. */
3469           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3470           if (!iv_included)
3471             memcpy(iv + 4, keymat->send_iv, 8);
3472           else
3473             memset(iv + 4, 0, 12);
3474         }
3475
3476         silc_cipher_set_iv(*ret_receive_key, iv);
3477       } else {
3478         /* Other modes */
3479         silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
3480       }
3481     }
3482     if (ret_hmac_send)
3483       silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
3484                         keymat->hmac_key_len);
3485     if (ret_hmac_receive)
3486       silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
3487                         keymat->hmac_key_len);
3488   } else {
3489     if (ret_send_key) {
3490       silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
3491                           keymat->enc_key_len, TRUE);
3492
3493       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
3494         /* Counter mode */
3495         if (!ske->rekeying) {
3496           /* Set IV. */
3497           memcpy(iv, ske->hash, 4);
3498           if (!iv_included)
3499             memcpy(iv + 4, keymat->send_iv, 8);
3500         } else {
3501           /* Rekey, recompute the truncated hash value. */
3502           silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
3503           if (!iv_included)
3504             memcpy(iv + 4, keymat->send_iv, 8);
3505           else
3506             memset(iv + 4, 0, 12);
3507         }
3508
3509         silc_cipher_set_iv(*ret_send_key, iv);
3510       } else {
3511         /* Other modes */
3512         silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
3513       }
3514     }
3515     if (ret_receive_key) {
3516       silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
3517                           keymat->enc_key_len, FALSE);
3518
3519       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
3520         /* Counter mode */
3521         if (!ske->rekeying) {
3522           /* Set IV.  If IV Included flag was negotiated we only set the
3523              truncated hash value. */
3524           memcpy(iv, ske->hash, 4);
3525           if (!iv_included)
3526             memcpy(iv + 4, keymat->receive_iv, 8);
3527         } else {
3528           /* Rekey, recompute the truncated hash value. */
3529           silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
3530           if (!iv_included)
3531             memcpy(iv + 4, keymat->receive_iv, 8);
3532           else
3533             memset(iv + 4, 0, 12);
3534         }
3535
3536         silc_cipher_set_iv(*ret_receive_key, iv);
3537       } else {
3538         /* Other modes */
3539         silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
3540       }
3541     }
3542     if (ret_hmac_send)
3543       silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
3544                         keymat->hmac_key_len);
3545     if (ret_hmac_receive)
3546       silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
3547                         keymat->hmac_key_len);
3548   }
3549
3550   return TRUE;
3551 }
3552
3553 const char *silc_ske_status_string[] =
3554 {
3555   /* Official */
3556   "Ok",
3557   "Unexpected error occurred",
3558   "Bad payload in packet",
3559   "Unsupported group",
3560   "Unsupported cipher",
3561   "Unsupported PKCS",
3562   "Unsupported hash function",
3563   "Unsupported HMAC",
3564   "Unsupported public key (or certificate)",
3565   "Incorrect signature",
3566   "Bad or unsupported version",
3567   "Invalid cookie",
3568
3569   /* Other errors */
3570   "Remote did not provide public key",
3571   "Bad reserved field in packet",
3572   "Bad payload length in packet",
3573   "Error computing signature",
3574   "System out of memory",
3575   "Key exchange timeout",
3576
3577   NULL
3578 };
3579
3580 /* Maps status to readable string and returns the string. If string is not
3581    found and empty character string ("") is returned. */
3582
3583 const char *silc_ske_map_status(SilcSKEStatus status)
3584 {
3585   int i;
3586
3587   for (i = 0; silc_ske_status_string[i]; i++)
3588     if (status == i)
3589       return silc_ske_status_string[i];
3590
3591   return "";
3592 }
3593
3594 /* Parses remote host's version string. */
3595
3596 SilcBool silc_ske_parse_version(SilcSKE ske,
3597                                 SilcUInt32 *protocol_version,
3598                                 char **protocol_version_string,
3599                                 SilcUInt32 *software_version,
3600                                 char **software_version_string,
3601                                 char **vendor_version)
3602 {
3603   return silc_parse_version_string(ske->remote_version,
3604                                    protocol_version,
3605                                    protocol_version_string,
3606                                    software_version,
3607                                    software_version_string,
3608                                    vendor_version);
3609 }
3610
3611 /* Get security properties */
3612
3613 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
3614 {
3615   return ske->prop;
3616 }
3617
3618 /* Get key material */
3619
3620 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
3621 {
3622   return ske->keymat;
3623 }