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