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