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