Noise-C
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
handshakestate.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "internal.h"
24 #include <string.h>
25 #include <stdlib.h>
26 
60 static int noise_handshakestate_requirements
61  (NoisePatternFlags_t flags, int prefix_id, int role, int is_fallback)
62 {
63  int requirements = 0;
64  if (flags & NOISE_PAT_FLAG_LOCAL_STATIC) {
65  requirements |= NOISE_REQ_LOCAL_REQUIRED;
66  }
67  if (flags & NOISE_PAT_FLAG_LOCAL_REQUIRED) {
68  requirements |= NOISE_REQ_LOCAL_REQUIRED;
69  requirements |= NOISE_REQ_LOCAL_PREMSG;
70  }
71  if (flags & NOISE_PAT_FLAG_REMOTE_REQUIRED) {
72  requirements |= NOISE_REQ_REMOTE_REQUIRED;
73  requirements |= NOISE_REQ_REMOTE_PREMSG;
74  }
75  if (flags & (NOISE_PAT_FLAG_REMOTE_EPHEM_REQ |
77  if (is_fallback)
78  requirements |= NOISE_REQ_FALLBACK_PREMSG;
79  }
80  if (prefix_id == NOISE_PREFIX_PSK) {
81  requirements |= NOISE_REQ_PSK;
82  }
83  return requirements;
84 }
85 
102 static int noise_handshakestate_new
103  (NoiseHandshakeState **state, NoiseSymmetricState *symmetric, int role)
104 {
105  const uint8_t *pattern;
106  int dh_id;
107  int hybrid_id;
108  NoisePatternFlags_t flags;
109  int extra_reqs = 0;
110  int err;
111  int local_dh_role;
112  int remote_dh_role;
113 
114  /* Locate the information for the current handshake pattern */
115  pattern = noise_pattern_lookup(symmetric->id.pattern_id);
116  if (!pattern) {
117  noise_symmetricstate_free(symmetric);
118  return NOISE_ERROR_UNKNOWN_ID;
119  }
120  flags = ((NoisePatternFlags_t)(pattern[0])) |
121  (((NoisePatternFlags_t)(pattern[1])) << 8);
122  if ((flags & NOISE_PAT_FLAG_REMOTE_REQUIRED) != 0)
123  extra_reqs |= NOISE_REQ_FALLBACK_POSSIBLE;
124  if (role == NOISE_ROLE_RESPONDER) {
125  /* Reverse the pattern flags so that the responder is "local" */
126  flags = noise_pattern_reverse_flags(flags);
127  }
128 
129  /* Determine the role to use for DHState objects */
130  if ((flags & NOISE_PAT_FLAG_REMOTE_EPHEM_REQ) != 0) {
131  /* Fallback pattern - reverse the DHState role */
132  if (role == NOISE_ROLE_INITIATOR) {
133  local_dh_role = NOISE_ROLE_RESPONDER;
134  remote_dh_role = NOISE_ROLE_INITIATOR;
135  } else {
136  local_dh_role = NOISE_ROLE_INITIATOR;
137  remote_dh_role = NOISE_ROLE_RESPONDER;
138  }
139  } else {
140  /* Regular pattern */
141  if (role == NOISE_ROLE_INITIATOR) {
142  local_dh_role = NOISE_ROLE_INITIATOR;
143  remote_dh_role = NOISE_ROLE_RESPONDER;
144  } else {
145  local_dh_role = NOISE_ROLE_RESPONDER;
146  remote_dh_role = NOISE_ROLE_INITIATOR;
147  }
148  }
149 
150  /* Create the HandshakeState object */
151  *state = noise_new(NoiseHandshakeState);
152  if (!(*state)) {
153  noise_symmetricstate_free(symmetric);
154  return NOISE_ERROR_NO_MEMORY;
155  }
156 
157  /* Initialize the HandshakeState */
158  (*state)->requirements = extra_reqs | noise_handshakestate_requirements
159  (flags, symmetric->id.prefix_id, role, 0);
160  (*state)->action = NOISE_ACTION_NONE;
161  (*state)->tokens = pattern + 2;
162  (*state)->role = role;
163  (*state)->symmetric = symmetric;
164 
165  /* Create DHState objects for all of the keys we will need later */
166  err = NOISE_ERROR_NONE;
167  dh_id = symmetric->id.dh_id;
168  hybrid_id = symmetric->id.hybrid_id;
169  if ((flags & NOISE_PAT_FLAG_LOCAL_STATIC) != 0) {
170  err = noise_dhstate_new_by_id(&((*state)->dh_local_static), dh_id);
171  }
172  if ((flags & NOISE_PAT_FLAG_LOCAL_EPHEMERAL) != 0 && err == NOISE_ERROR_NONE) {
173  err = noise_dhstate_new_by_id(&((*state)->dh_local_ephemeral), dh_id);
174  }
175  if ((flags & NOISE_PAT_FLAG_LOCAL_HYBRID) != 0 && err == NOISE_ERROR_NONE) {
176  if (hybrid_id != NOISE_DH_NONE)
177  err = noise_dhstate_new_by_id(&((*state)->dh_local_hybrid), hybrid_id);
178  else
180  } else if (hybrid_id != NOISE_DH_NONE) {
182  }
183  if ((flags & NOISE_PAT_FLAG_REMOTE_STATIC) != 0 && err == NOISE_ERROR_NONE) {
184  err = noise_dhstate_new_by_id(&((*state)->dh_remote_static), dh_id);
185  }
186  if ((flags & NOISE_PAT_FLAG_REMOTE_EPHEMERAL) != 0 && err == NOISE_ERROR_NONE) {
187  err = noise_dhstate_new_by_id(&((*state)->dh_remote_ephemeral), dh_id);
188  }
189  if ((flags & NOISE_PAT_FLAG_REMOTE_HYBRID) != 0 && err == NOISE_ERROR_NONE) {
190  if (hybrid_id != NOISE_DH_NONE)
191  err = noise_dhstate_new_by_id(&((*state)->dh_remote_hybrid), hybrid_id);
192  else
194  } else if (hybrid_id != NOISE_DH_NONE) {
196  }
197 
198  /* Set the roles for all DHState objects except those for hybrid
199  forward secrecy. Those roles are implicit in whether the "f"
200  or "g" token is used to refer to the value */
201  noise_dhstate_set_role((*state)->dh_local_ephemeral, local_dh_role);
202  noise_dhstate_set_role((*state)->dh_local_static, local_dh_role);
203  noise_dhstate_set_role((*state)->dh_remote_ephemeral, remote_dh_role);
204  noise_dhstate_set_role((*state)->dh_remote_static, remote_dh_role);
205 
206  /* If the DH algorithm is ephemeral-only, then we need to apply some
207  * extra checks on the pattern: essentially, only "NN" is possible.
208  * This check isn't needed for the hybrid secrecy DH objects as they
209  * are by definition ephemeral-only */
210  if (err == NOISE_ERROR_NONE) {
211  if ((*state)->dh_local_static && (*state)->dh_local_static->ephemeral_only)
213  if ((*state)->dh_remote_static && (*state)->dh_remote_static->ephemeral_only)
215  if ((*state)->dh_local_ephemeral && (*state)->dh_local_ephemeral->ephemeral_only) {
216  if (!((*state)->dh_remote_ephemeral))
218  } else if ((*state)->dh_remote_ephemeral && (*state)->dh_remote_ephemeral->ephemeral_only) {
220  }
221  }
222 
223  /* Bail out if we had an error trying to create the DHState objects */
224  if (err != NOISE_ERROR_NONE) {
226  return err;
227  }
228 
229  /* Ready to go */
230  return NOISE_ERROR_NONE;
231 }
232 
257  (NoiseHandshakeState **state, const NoiseProtocolId *protocol_id, int role)
258 {
259  NoiseSymmetricState *symmetric;
260  int err;
261 
262  /* Validate the parameters */
263  if (!state)
265  *state = 0;
266  if (!protocol_id)
268  if (role != NOISE_ROLE_INITIATOR && role != NOISE_ROLE_RESPONDER)
270 
271  /* Create the SymmetricState object */
272  err = noise_symmetricstate_new_by_id(&symmetric, protocol_id);
273  if (err != NOISE_ERROR_NONE)
274  return err;
275 
276  /* Create the HandshakeState object */
277  return noise_handshakestate_new(state, symmetric, role);
278 }
279 
303  (NoiseHandshakeState **state, const char *protocol_name, int role)
304 {
305  NoiseSymmetricState *symmetric;
306  int err;
307 
308  /* Validate the parameters */
309  if (!state)
311  *state = 0;
312  if (!protocol_name)
314  if (role != NOISE_ROLE_INITIATOR && role != NOISE_ROLE_RESPONDER)
316 
317  /* Create the SymmetricState object */
318  err = noise_symmetricstate_new_by_name(&symmetric, protocol_name);
319  if (err != NOISE_ERROR_NONE)
320  return err;
321 
322  /* Create the HandshakeState object */
323  return noise_handshakestate_new(state, symmetric, role);
324 }
325 
337 {
338  /* Bail out if no handshake state */
339  if (!state)
341 
342  /* Free the sub objects that are hanging off the handshakestate */
343  if (state->symmetric)
345  if (state->dh_local_static)
347  if (state->dh_local_ephemeral)
349  if (state->dh_local_hybrid)
351  if (state->dh_remote_static)
353  if (state->dh_remote_ephemeral)
355  if (state->dh_remote_hybrid)
357  if (state->dh_fixed_ephemeral)
359  if (state->dh_fixed_hybrid)
361  noise_free(state->prologue, state->prologue_len);
362 
363  /* Clean and free the memory for "state" */
364  noise_free(state, state->size);
365  return NOISE_ERROR_NONE;
366 }
367 
377 {
378  return state ? state->role : 0;
379 }
380 
394 {
395  /* Validate the parameters */
396  if (!state || !id)
398 
399  /* Copy the protocol identifiers to the caller's buffer */
400  *id = state->symmetric->id;
401  return NOISE_ERROR_NONE;
402 }
403 
418  (const NoiseHandshakeState *state)
419 {
420  return state ? state->dh_local_static : 0;
421 }
422 
439  (const NoiseHandshakeState *state)
440 {
441  return state ? state->dh_remote_static : 0;
442 }
443 
460 {
461  if (!state || !state->dh_local_ephemeral)
462  return 0;
463 
464  if (!state->dh_fixed_ephemeral) {
466  (&(state->dh_fixed_ephemeral), state->symmetric->id.dh_id)
467  != NOISE_ERROR_NONE) {
468  return 0;
469  }
471  (state->dh_fixed_ephemeral,
473  }
474 
475  return state->dh_fixed_ephemeral;
476 }
477 
496 {
497  if (!state || !state->dh_local_hybrid)
498  return 0;
499 
500  if (!state->dh_fixed_hybrid) {
502  (&(state->dh_fixed_hybrid), state->symmetric->id.hybrid_id)
503  != NOISE_ERROR_NONE) {
504  return 0;
505  }
506 
507  /* Normally hybrid keys do not get a role until the "f" or "g"
508  tokens are encountered. However for fixed test vectors we
509  need to know the size of the private key ahead of time and
510  hence the role. Predict the future hybrid role from the
511  current ephemeral role. */
513  (state->dh_fixed_hybrid,
515  }
516 
517  return state->dh_fixed_hybrid;
518 }
519 
532 {
533  if (!state || state->pre_shared_key_len)
534  return 0;
535  else
536  return (state->requirements & NOISE_REQ_PSK) != 0;
537 }
538 
551 {
552  if (!state)
553  return 0;
554  else
555  return state->pre_shared_key_len != 0;
556 }
557 
579  (NoiseHandshakeState *state, const uint8_t *key, size_t key_len)
580 {
581  /* Validate the parameters and state */
582  if (!state || !key)
584  if (key_len != NOISE_PSK_LEN)
586  if (state->symmetric->id.prefix_id != NOISE_PREFIX_PSK)
588  if (state->action != NOISE_ACTION_NONE)
590 
591  /* Record the pre-shared key for use in noise_handshakestate_start() */
592  memcpy(state->pre_shared_key, key, key_len);
593  state->pre_shared_key_len = key_len;
594  return NOISE_ERROR_NONE;
595 }
596 
619  (NoiseHandshakeState *state, const void *prologue, size_t prologue_len)
620 {
621  /* Validate the parameters */
622  if (!state || !prologue)
624  if (state->action != NOISE_ACTION_NONE)
626 
627  /* Make a copy of the prologue for later */
628  if (state->prologue && state->prologue_len == prologue_len) {
629  memcpy(state->prologue, prologue, prologue_len);
630  } else {
631  noise_free(state->prologue, state->prologue_len);
632  if (prologue_len) {
633  state->prologue = (uint8_t *)malloc(prologue_len);
634  if (!(state->prologue)) {
635  state->prologue_len = 0;
636  return NOISE_ERROR_NO_MEMORY;
637  }
638  memcpy(state->prologue, prologue, prologue_len);
639  } else {
640  state->prologue = 0;
641  }
642  state->prologue_len = prologue_len;
643  }
644  return NOISE_ERROR_NONE;
645 }
646 
664 {
665  if (!state)
666  return 0;
667  if ((state->requirements & NOISE_REQ_LOCAL_REQUIRED) == 0)
668  return 0;
670 }
671 
686 {
687  if (!state || !state->dh_local_static)
688  return 0;
690 }
691 
712 {
713  if (!state)
714  return 0;
715  if ((state->requirements & NOISE_REQ_REMOTE_REQUIRED) == 0)
716  return 0;
718 }
719 
736 {
737  if (!state || !state->dh_remote_static)
738  return 0;
740 }
741 
748 static void noise_handshakestate_mix_public_key
749  (NoiseHandshakeState *state, const NoiseDHState *dh)
750 {
753  (state->symmetric, dh->public_key, dh->public_key_len);
754  }
755 }
756 
763 static void noise_handshakestate_mix_chaining_key
764  (NoiseHandshakeState *state, const NoiseDHState *dh)
765 {
768  (state->symmetric, dh->public_key, dh->public_key_len);
769  }
770 }
771 
801 {
802  /* Validate the parameter */
803  if (!state)
805  if (state->action != NOISE_ACTION_NONE)
808  (state->requirements & NOISE_REQ_FALLBACK_PREMSG) == 0)
810 
811  /* Check that we have satisfied all of the pattern requirements */
812  if ((state->requirements & NOISE_REQ_LOCAL_REQUIRED) != 0 &&
815  if ((state->requirements & NOISE_REQ_REMOTE_REQUIRED) != 0 &&
818  if ((state->requirements & NOISE_REQ_PSK) != 0 &&
819  state->pre_shared_key_len == 0)
821 
822  /* Hash the prologue value */
823  if (state->prologue_len) {
825  (state->symmetric, state->prologue, state->prologue_len);
826  } else {
827  /* No prologue, so hash an empty one */
829  (state->symmetric, state->pre_shared_key, 0);
830  }
831 
832  /* Mix the pre shared key into the chaining key and handshake hash */
833  if (state->pre_shared_key_len) {
834  uint8_t temp[NOISE_MAX_HASHLEN];
835  NoiseHashState *hash = state->symmetric->hash;
837  (hash, state->symmetric->ck, hash->hash_len,
838  state->pre_shared_key, state->pre_shared_key_len,
839  state->symmetric->ck, hash->hash_len, temp, hash->hash_len);
840  noise_symmetricstate_mix_hash(state->symmetric, temp, hash->hash_len);
841  noise_clean(temp, sizeof(temp));
842  }
843 
844  /* Mix the pre-supplied public keys into the handshake hash */
845  if (state->role == NOISE_ROLE_INITIATOR) {
847  noise_handshakestate_mix_public_key(state, state->dh_local_static);
849  noise_handshakestate_mix_public_key(state, state->dh_remote_ephemeral);
850  if (state->dh_remote_hybrid) {
851  noise_handshakestate_mix_public_key
852  (state, state->dh_remote_hybrid);
853  }
854  if ((state->requirements & NOISE_REQ_PSK) != 0) {
855  noise_handshakestate_mix_chaining_key
856  (state, state->dh_remote_ephemeral);
857  }
858  }
860  noise_handshakestate_mix_public_key(state, state->dh_remote_static);
861  } else {
863  noise_handshakestate_mix_public_key(state, state->dh_remote_static);
865  noise_handshakestate_mix_public_key(state, state->dh_local_ephemeral);
866  if (state->dh_local_hybrid) {
867  noise_handshakestate_mix_public_key
868  (state, state->dh_local_hybrid);
869  }
870  if ((state->requirements & NOISE_REQ_PSK) != 0) {
871  noise_handshakestate_mix_chaining_key
872  (state, state->dh_local_ephemeral);
873  }
874  }
876  noise_handshakestate_mix_public_key(state, state->dh_local_static);
877  }
878 
879  /* The handshake has now officially started */
880  if (state->role == NOISE_ROLE_INITIATOR)
882  else
884  return NOISE_ERROR_NONE;
885 }
886 
922 {
924 }
925 
974 {
975  char name[NOISE_MAX_PROTOCOL_NAME];
976  size_t hash_len;
977  size_t name_len;
978  NoiseProtocolId id;
979  const uint8_t *pattern;
980  NoisePatternFlags_t flags;
981  int err;
982 
983  /* Validate the parameter */
984  if (!state)
986 
987  /* The original pattern must end in "K" for fallback to be possible */
988  if (state->symmetric->id.pattern_id < NOISE_PATTERN_NN ||
991 
992  /* Check that "pattern_id" supports fallback */
993  pattern = noise_pattern_lookup(pattern_id);
994  if (!pattern)
996  flags = ((NoisePatternFlags_t)(pattern[0])) |
997  (((NoisePatternFlags_t)(pattern[1])) << 8);
998  if ((flags & NOISE_PAT_FLAG_REMOTE_EPHEM_REQ) == 0)
1000 
1001  /* The initiator should be waiting for a return message from the
1002  responder, and the responder should have failed on the first
1003  handshake message from the initiator. We also allow the
1004  responder to fallback after processing the first message
1005  successfully; it decides to always fall back anyway. */
1006  if (state->role == NOISE_ROLE_INITIATOR) {
1007  if (state->action != NOISE_ACTION_FAILED &&
1012  if (state->dh_local_hybrid &&
1015  } else {
1016  if (state->action != NOISE_ACTION_FAILED &&
1021  if (state->dh_remote_hybrid &&
1024  }
1025 
1026  /* Format a new protocol name for the fallback variant */
1027  id = state->symmetric->id;
1028  id.pattern_id = pattern_id;
1029  err = noise_protocol_id_to_name(name, sizeof(name), &id);
1030  if (err != NOISE_ERROR_NONE)
1031  return err;
1032 
1033  /* Convert the HandshakeState to the fallback pattern */
1034  state->symmetric->id.pattern_id = pattern_id;
1035  if (state->role == NOISE_ROLE_INITIATOR) {
1039  state->role = NOISE_ROLE_RESPONDER;
1040  } else {
1043  if (!(flags & NOISE_PAT_FLAG_REMOTE_REQUIRED))
1045  state->role = NOISE_ROLE_INITIATOR;
1046  }
1047 
1048  /* Start a new token pattern for the fallback */
1049  state->tokens = pattern + 2;
1050  state->action = NOISE_ACTION_NONE;
1051 
1052  /* Set up the key requirements for the fallback */
1053  if (state->role == NOISE_ROLE_RESPONDER) {
1054  flags = noise_pattern_reverse_flags(flags);
1055  }
1056  state->requirements = noise_handshakestate_requirements
1057  (flags, id.prefix_id, state->role, 1);
1058 
1059  /* Re-initialize the chaining key "ck" and the handshake hash "h" from
1060  the new protocol name. If the name is too long, hash it down first */
1061  name_len = strlen(name);
1062  hash_len = noise_hashstate_get_hash_length(state->symmetric->hash);
1063  if (name_len <= hash_len) {
1064  memcpy(state->symmetric->h, name, name_len);
1065  memset(state->symmetric->h + name_len, 0, hash_len - name_len);
1066  } else {
1068  (state->symmetric->hash, (const uint8_t *)name, name_len,
1069  state->symmetric->h, hash_len);
1070  }
1071  memcpy(state->symmetric->ck, state->symmetric->h, hash_len);
1072 
1073  /* Reset the encryption key within the symmetric state to empty */
1074  state->symmetric->cipher->has_key = 0;
1075  state->symmetric->cipher->n = 0;
1076 
1077  /* Ready to go */
1078  return NOISE_ERROR_NONE;
1079 }
1080 
1113 {
1114  return state ? state->action : NOISE_ACTION_NONE;
1115 }
1116 
1128 static int noise_handshake_mix_dh
1130  const NoiseDHState *public_key)
1131 {
1132  size_t len = private_key->shared_key_len;
1133  uint8_t *shared = alloca(len);
1134  int err = noise_dhstate_calculate(private_key, public_key, shared, len);
1135  noise_symmetricstate_mix_key(state->symmetric, shared, len);
1136  noise_clean(shared, len);
1137  return err;
1138 }
1139 
1151 static int noise_handshakestate_write
1152  (NoiseHandshakeState *state, NoiseBuffer *message, const NoiseBuffer *payload)
1153 {
1154  NoiseBuffer rest;
1155  size_t len;
1156  size_t mac_len;
1157  uint8_t token;
1158  int err;
1159 
1160  /* Process tokens until the direction changes or the pattern ends */
1161  for (;;) {
1162  token = *(state->tokens);
1163  if (token == NOISE_TOKEN_END) {
1164  /* The pattern has finished, so the next action is "split" */
1165  state->action = NOISE_ACTION_SPLIT;
1166  break;
1167  } else if (token == NOISE_TOKEN_FLIP_DIR) {
1168  /* Changing directions, so this message is complete and
1169  the next action is "read message". */
1170  ++(state->tokens);
1172  break;
1173  }
1174 
1175  /* Set "rest" to the rest of the "message" buffer after the
1176  current size. This is the space we have left to write
1177  handshake values while processing this token. */
1178  rest.data = message->data + message->size;
1179  rest.size = 0;
1180  rest.max_size = message->max_size - message->size;
1181 
1182  /* Process the token */
1183  err = NOISE_ERROR_NONE;
1184  switch (token) {
1185  case NOISE_TOKEN_E:
1186  /* Generate a local ephemeral keypair and add the public
1187  key to the message. If we are running fixed vector tests,
1188  then the ephemeral key may have already been provided. */
1189  if (!state->dh_local_ephemeral)
1191  if (!state->dh_fixed_ephemeral) {
1193  (state->dh_local_ephemeral, state->dh_remote_ephemeral);
1194  } else {
1195  /* Use the fixed ephemeral key provided by the test harness.
1196  To support New Hope we need to perform a dependent copy */
1197  state->dh_local_ephemeral->key_type =
1198  state->dh_fixed_ephemeral->key_type;
1199  err = (*(state->dh_local_ephemeral->copy))
1200  (state->dh_local_ephemeral, state->dh_fixed_ephemeral,
1201  state->dh_remote_ephemeral);
1202  }
1203  if (err != NOISE_ERROR_NONE)
1204  break;
1205  len = state->dh_local_ephemeral->public_key_len;
1206  if (rest.max_size < len)
1208  memcpy(rest.data, state->dh_local_ephemeral->public_key, len);
1209  noise_symmetricstate_mix_hash(state->symmetric, rest.data, len);
1210  rest.size += len;
1211 
1212  /* If the protocol is using pre-shared keys, then also mix
1213  the local ephemeral key into the chaining key */
1214  if (state->symmetric->id.prefix_id == NOISE_PREFIX_PSK) {
1216  (state->symmetric,
1217  state->dh_local_ephemeral->public_key, len);
1218  }
1219  break;
1220  case NOISE_TOKEN_S:
1221  /* Encrypt the local static public key and add it to the message */
1222  if (!state->dh_local_static)
1224  len = state->dh_local_static->public_key_len;
1226  if (rest.max_size < (len + mac_len))
1228  memcpy(rest.data, state->dh_local_static->public_key, len);
1229  rest.size += len;
1230  err = noise_symmetricstate_encrypt_and_hash(state->symmetric, &rest);
1231  if (err != NOISE_ERROR_NONE)
1232  break;
1233  break;
1234  case NOISE_TOKEN_EE:
1235  /* DH operation with initiator and responder ephemeral keys */
1236  err = noise_handshake_mix_dh
1237  (state, state->dh_local_ephemeral, state->dh_remote_ephemeral);
1238  break;
1239  case NOISE_TOKEN_ES:
1240  /* DH operation with initiator ephemeral and responder static keys */
1241  if (state->role == NOISE_ROLE_INITIATOR) {
1242  err = noise_handshake_mix_dh
1243  (state, state->dh_local_ephemeral, state->dh_remote_static);
1244  } else {
1245  err = noise_handshake_mix_dh
1246  (state, state->dh_local_static, state->dh_remote_ephemeral);
1247  }
1248  break;
1249  case NOISE_TOKEN_SE:
1250  /* DH operation with initiator static and responder ephemeral keys */
1251  if (state->role == NOISE_ROLE_INITIATOR) {
1252  err = noise_handshake_mix_dh
1253  (state, state->dh_local_static, state->dh_remote_ephemeral);
1254  } else {
1255  err = noise_handshake_mix_dh
1256  (state, state->dh_local_ephemeral, state->dh_remote_static);
1257  }
1258  break;
1259  case NOISE_TOKEN_SS:
1260  /* DH operation with initiator and responder static keys */
1261  err = noise_handshake_mix_dh
1262  (state, state->dh_local_static, state->dh_remote_static);
1263  break;
1264  case NOISE_TOKEN_F:
1265  /* Generate a local hybrid keypair and add the encrypted public
1266  key to the message. If we are running fixed vector tests,
1267  then the hybrid key may have already been provided. */
1268  if (!state->dh_local_hybrid || !state->dh_remote_hybrid)
1273  } else {
1276  }
1277  if (!state->dh_fixed_hybrid) {
1279  (state->dh_local_hybrid, state->dh_remote_hybrid);
1280  } else {
1281  /* Use the fixed hybrid key provided by the test harness.
1282  To support New Hope we need to perform a dependent copy */
1283  state->dh_local_hybrid->key_type =
1284  state->dh_fixed_hybrid->key_type;
1285  err = (*(state->dh_local_hybrid->copy))
1286  (state->dh_local_hybrid, state->dh_fixed_hybrid,
1287  state->dh_remote_hybrid);
1288  }
1289  if (err != NOISE_ERROR_NONE)
1290  break;
1291  len = state->dh_local_hybrid->public_key_len;
1293  if (rest.max_size < (len + mac_len))
1295  memcpy(rest.data, state->dh_local_hybrid->public_key, len);
1296  rest.size += len;
1297  err = noise_symmetricstate_encrypt_and_hash(state->symmetric, &rest);
1298  if (err != NOISE_ERROR_NONE)
1299  break;
1300  break;
1301  case NOISE_TOKEN_FF:
1302  /* DH operation with local and remote hybrid keys */
1303  err = noise_handshake_mix_dh
1304  (state, state->dh_local_hybrid, state->dh_remote_hybrid);
1305  break;
1306  default:
1307  /* Unknown token code in the pattern. This shouldn't happen.
1308  If it does, then abort immediately. */
1310  break;
1311  }
1312  if (err != NOISE_ERROR_NONE)
1313  return err;
1314  message->size += rest.size;
1315  ++(state->tokens);
1316  }
1317 
1318  /* Add the payload to the message buffer and encrypt it */
1320  if ((message->max_size - message->size) < mac_len)
1322  if (payload) {
1323  if ((message->max_size - message->size - mac_len) < payload->size)
1325  rest.data = message->data + message->size;
1326  rest.size = payload->size;
1327  rest.max_size = message->max_size - message->size;
1328  memcpy(rest.data, payload->data, payload->size);
1329  } else {
1330  rest.data = message->data + message->size;
1331  rest.size = 0;
1332  rest.max_size = message->max_size - message->size;
1333  }
1334  err = noise_symmetricstate_encrypt_and_hash(state->symmetric, &rest);
1335  if (err != NOISE_ERROR_NONE)
1336  return err;
1337 
1338  /* Return the final size to the caller */
1339  message->size += rest.size;
1340  return NOISE_ERROR_NONE;
1341 }
1342 
1380  (NoiseHandshakeState *state, NoiseBuffer *message, const NoiseBuffer *payload)
1381 {
1382  int err;
1383 
1384  /* Validate the parameters */
1385  if (!message)
1387  message->size = 0;
1388  if (!state || !(message->data))
1390  if (payload && !(payload->data))
1392  if (state->action != NOISE_ACTION_WRITE_MESSAGE)
1394 
1395  /* Perform the write */
1396  err = noise_handshakestate_write(state, message, payload);
1397  if (err != NOISE_ERROR_NONE) {
1398  /* Set the state to "failed" and empty the message buffer */
1399  state->action = NOISE_ACTION_FAILED;
1400  message->size = 0;
1401  }
1402  return err;
1403 }
1404 
1419 static int noise_handshakestate_read
1420  (NoiseHandshakeState *state, NoiseBuffer *message, NoiseBuffer *payload)
1421 {
1422  NoiseBuffer msg;
1423  NoiseBuffer msg2;
1424  size_t len;
1425  size_t mac_len;
1426  uint8_t token;
1427  int err;
1428 
1429  /* Make a copy of the message buffer. As we process tokens, the copy
1430  will become shorter and shorter until only the payload is left. */
1431  msg = *message;
1432 
1433  /* Process tokens until the direction changes or the pattern ends */
1434  for (;;) {
1435  token = *(state->tokens);
1436  if (token == NOISE_TOKEN_END) {
1437  /* The pattern has finished, so the next action is "split" */
1438  state->action = NOISE_ACTION_SPLIT;
1439  break;
1440  } else if (token == NOISE_TOKEN_FLIP_DIR) {
1441  /* Changing directions, so this message is complete and
1442  the next action is "read message". */
1443  ++(state->tokens);
1445  break;
1446  }
1447  err = NOISE_ERROR_NONE;
1448  switch (token) {
1449  case NOISE_TOKEN_E:
1450  /* Save the remote ephemeral key and hash it */
1451  if (!state->dh_remote_ephemeral)
1453  len = state->dh_remote_ephemeral->public_key_len;
1454  if (msg.size < len)
1457  (state->symmetric, msg.data, len);
1458  if (err != NOISE_ERROR_NONE)
1459  break;
1461  (state->dh_remote_ephemeral, msg.data, len);
1462  if (err != NOISE_ERROR_NONE)
1463  break;
1465  /* The remote ephemeral key is null, which means that it is
1466  not contributing anything to the security of the session
1467  and is in fact downgrading the security to "none at all"
1468  in some of the message patterns. Reject all such keys. */
1470  }
1471  msg.data += len;
1472  msg.size -= len;
1473  msg.max_size -= len;
1474 
1475  /* If the protocol is using pre-shared keys, then also mix
1476  the remote ephemeral key into the chaining key */
1477  if (state->symmetric->id.prefix_id == NOISE_PREFIX_PSK) {
1479  (state->symmetric,
1480  state->dh_remote_ephemeral->public_key, len);
1481  }
1482  break;
1483  case NOISE_TOKEN_S:
1484  /* Decrypt and read the remote static key */
1485  if (!state->dh_remote_static)
1488  len = state->dh_remote_static->public_key_len + mac_len;
1489  if (msg.size < len)
1491  msg2.data = msg.data;
1492  msg2.size = len;
1493  msg2.max_size = len;
1495  (state->symmetric, &msg2);
1496  if (err != NOISE_ERROR_NONE)
1497  break;
1499  (state->dh_remote_static, msg2.data, msg2.size);
1500  if (err != NOISE_ERROR_NONE)
1501  break;
1502  msg.data += len;
1503  msg.size -= len;
1504  msg.max_size -= len;
1505  break;
1506  case NOISE_TOKEN_EE:
1507  /* DH operation with initiator and responder ephemeral keys */
1508  err = noise_handshake_mix_dh
1509  (state, state->dh_local_ephemeral, state->dh_remote_ephemeral);
1510  break;
1511  case NOISE_TOKEN_ES:
1512  /* DH operation with initiator ephemeral and responder static keys */
1513  if (state->role == NOISE_ROLE_INITIATOR) {
1514  err = noise_handshake_mix_dh
1515  (state, state->dh_local_ephemeral, state->dh_remote_static);
1516  } else {
1517  err = noise_handshake_mix_dh
1518  (state, state->dh_local_static, state->dh_remote_ephemeral);
1519  }
1520  break;
1521  case NOISE_TOKEN_SE:
1522  /* DH operation with initiator static and responder ephemeral keys */
1523  if (state->role == NOISE_ROLE_INITIATOR) {
1524  err = noise_handshake_mix_dh
1525  (state, state->dh_local_static, state->dh_remote_ephemeral);
1526  } else {
1527  err = noise_handshake_mix_dh
1528  (state, state->dh_local_ephemeral, state->dh_remote_static);
1529  }
1530  break;
1531  case NOISE_TOKEN_SS:
1532  /* DH operation with initiator and responder static keys */
1533  err = noise_handshake_mix_dh
1534  (state, state->dh_local_static, state->dh_remote_static);
1535  break;
1536  case NOISE_TOKEN_F:
1537  /* Decrypt and save the remote hybrid key */
1538  if (!state->dh_local_hybrid || !state->dh_remote_hybrid)
1543  } else {
1546  }
1548  len = state->dh_remote_hybrid->public_key_len + mac_len;
1549  if (msg.size < len)
1551  msg2.data = msg.data;
1552  msg2.size = len;
1553  msg2.max_size = len;
1555  (state->symmetric, &msg2);
1556  if (err != NOISE_ERROR_NONE)
1557  break;
1559  (state->dh_remote_hybrid, msg2.data, msg2.size);
1560  if (err != NOISE_ERROR_NONE)
1561  break;
1562  msg.data += len;
1563  msg.size -= len;
1564  msg.max_size -= len;
1566  /* The remote hybrid key is null, which means that it is
1567  not contributing anything to the security of the session
1568  and is in fact downgrading the security to "none at all"
1569  in some of the message patterns. Reject all such keys. */
1571  break;
1572  }
1573  break;
1574  case NOISE_TOKEN_FF:
1575  /* DH operation with local and remote hybrid keys */
1576  err = noise_handshake_mix_dh
1577  (state, state->dh_local_hybrid, state->dh_remote_hybrid);
1578  break;
1579  default:
1580  /* Unknown token code in the pattern. This shouldn't happen.
1581  If it does, then abort immediately. */
1583  break;
1584  }
1585  if (err != NOISE_ERROR_NONE)
1586  return err;
1587  ++(state->tokens);
1588  }
1589 
1590  /* Decrypt the remaining bytes and return them in the payload buffer */
1593  if (err != NOISE_ERROR_NONE)
1594  return err;
1595  if (payload) {
1596  if (msg.size > payload->max_size)
1598  memcpy(payload->data, msg.data, msg.size);
1599  payload->size = msg.size;
1600  }
1601  return NOISE_ERROR_NONE;
1602 }
1603 
1640  (NoiseHandshakeState *state, NoiseBuffer *message, NoiseBuffer *payload)
1641 {
1642  int err;
1643 
1644  /* Validate the parameters */
1645  if (payload) {
1646  if (!(payload->data))
1648  payload->size = 0;
1649  }
1650  if (!state || !message || !(message->data))
1652  if (message->size > message->max_size)
1654  if (state->action != NOISE_ACTION_READ_MESSAGE)
1656 
1657  /* Perform the read */
1658  err = noise_handshakestate_read(state, message, payload);
1659  noise_clean(message->data, message->size);
1660  if (err != NOISE_ERROR_NONE)
1661  state->action = NOISE_ACTION_FAILED;
1662  return err;
1663 }
1664 
1703 {
1704  int swap;
1705  int err;
1706 
1707  /* Validate the parameters */
1708  if (!state)
1710  if (!send && !receive)
1712  if (state->action != NOISE_ACTION_SPLIT)
1714  if (!state->symmetric->cipher)
1716 
1717  /* Do we need to swap the CipherState objects for the role? */
1718  swap = (state->role == NOISE_ROLE_RESPONDER);
1719 
1720  /* Split the CipherState objects out of the SymmetricState */
1721  if (swap)
1722  err = noise_symmetricstate_split(state->symmetric, receive, send);
1723  else
1724  err = noise_symmetricstate_split(state->symmetric, send, receive);
1725  if (err == NOISE_ERROR_NONE)
1726  state->action = NOISE_ACTION_COMPLETE;
1727  return err;
1728 }
1729 
1760  (const NoiseHandshakeState *state, uint8_t *hash, size_t max_len)
1761 {
1762  size_t hash_len;
1763 
1764  /* Validate the parameters */
1765  if (!state || !hash)
1767  if (state->action != NOISE_ACTION_SPLIT &&
1768  state->action != NOISE_ACTION_COMPLETE)
1770 
1771  /* Copy the handshake hash into the supplied buffer */
1772  hash_len = noise_hashstate_get_hash_length(state->symmetric->hash);
1773  if (hash_len <= max_len) {
1774  memcpy(hash, state->symmetric->h, hash_len);
1775  memset(hash + hash_len, 0, max_len - hash_len);
1776  } else {
1777  memcpy(hash, state->symmetric->h, max_len);
1778  }
1779  return NOISE_ERROR_NONE;
1780 }
1781 
#define NOISE_PSK_LEN
Standard length for pre-shared keys.
Definition: internal.h:53
#define NOISE_PAT_FLAG_LOCAL_EPHEMERAL
Definition: internal.h:603
Noise protocol name broken out into separate identifier fields.
Definition: names.h:33
int noise_handshakestate_has_pre_shared_key(const NoiseHandshakeState *state)
Determine if a HandshakeState object has already been configured with a pre shared key...
#define NOISE_ERROR_UNKNOWN_ID
Algorithm identifier is unknown.
uint16_t hash_len
Length of the output from this hash algorithm.
Definition: internal.h:160
#define NOISE_ACTION_NONE
No action is required of the application yet because the handshake has not started.
int noise_dhstate_clear_key(NoiseDHState *state)
Clears the key in a DHState object.
Definition: dhstate.c:622
void noise_clean(void *data, size_t size)
Cleans a block of memory to destroy its contents.
Definition: util.c:170
#define NOISE_ERROR_INVALID_STATE
Operation cannot be performed in the current state.
#define NOISE_TOKEN_FF
Definition: internal.h:597
size_t max_size
Definition: buffer.h:37
uint8_t ck[NOISE_MAX_HASHLEN]
Current value of the chaining key for the handshake.
Definition: internal.h:522
NoiseHashState * hash
Points to the HashState object for this SymmetricState.
Definition: internal.h:519
#define NOISE_ERROR_INVALID_PARAM
Invalid parameter to function; e.g. a NULL value.
uint8_t * public_key
Points to the public key in the subclass state.
Definition: internal.h:246
Internal structure of the NoiseHashState type.
Definition: internal.h:151
NoiseDHState * dh_fixed_ephemeral
Points to the object for the fixed ephemeral test key.
Definition: internal.h:570
#define NOISE_ACTION_COMPLETE
The HandshakeState has flagged that the handshake is over and and that noise_handshake_split() has be...
NoiseProtocolId id
Algorithm identifiers for the components of the protocol.
Definition: internal.h:506
#define NOISE_PAT_FLAG_LOCAL_REQUIRED
Definition: internal.h:608
#define NOISE_ERROR_NONE
Success, no error.
#define NOISE_KEY_TYPE_NO_KEY
Definition: internal.h:206
#define NOISE_TOKEN_EE
Definition: internal.h:592
int noise_handshakestate_get_role(const NoiseHandshakeState *state)
Gets the role that a HandshakeState object is playing.
int noise_handshakestate_get_protocol_id(const NoiseHandshakeState *state, NoiseProtocolId *id)
Gets the protocol identifier associated with a HandshakeState object.
const uint8_t * tokens
Points to the next message pattern tokens to be processed.
Definition: internal.h:546
uint8_t has_key
Non-zero if the key has been set on this cipher.
Definition: internal.h:67
size_t prologue_len
Length of the prologue value in bytes.
Definition: internal.h:585
size_t size
Total size of the structure, including DH key storage.
Definition: internal.h:534
int noise_handshakestate_read_message(NoiseHandshakeState *state, NoiseBuffer *message, NoiseBuffer *payload)
Reads a message payload using a HandshakeState.
#define NOISE_REQ_REMOTE_PREMSG
Definition: internal.h:647
int noise_dhstate_get_role(const NoiseDHState *state)
Gets the role that a DHState object will play in a handshake.
Definition: dhstate.c:805
int noise_handshakestate_get_handshake_hash(const NoiseHandshakeState *state, uint8_t *hash, size_t max_len)
Gets the handshake hash value once the handshake ends.
int noise_handshakestate_fallback(NoiseHandshakeState *state)
Falls back to the "XXfallback" handshake pattern.
int noise_handshakestate_free(NoiseHandshakeState *state)
Frees a HandshakeState object after destroying all sensitive material.
int noise_handshakestate_new_by_id(NoiseHandshakeState **state, const NoiseProtocolId *protocol_id, int role)
Creates a new HandshakeState object by protocol identifier.
uint8_t * data
Definition: buffer.h:35
#define NOISE_REQ_LOCAL_PREMSG
Definition: internal.h:645
int noise_handshakestate_needs_pre_shared_key(const NoiseHandshakeState *state)
Determine if a HandshakeState object requires a pre shared key.
int noise_symmetricstate_mix_key(NoiseSymmetricState *state, const uint8_t *input, size_t size)
Mixes new input data into the chaining key.
int noise_dhstate_new_by_id(NoiseDHState **state, int id)
Creates a new DHState object by its algorithm identifier.
Definition: dhstate.c:67
NoiseDHState * dh_remote_ephemeral
Points to the DHState object for remote ephemeral key.
Definition: internal.h:564
NoiseDHState * dh_local_ephemeral
Points to the DHState object for local ephemeral key.
Definition: internal.h:555
uint8_t h[NOISE_MAX_HASHLEN]
Current value of the handshake hash.
Definition: internal.h:525
int noise_handshakestate_set_pre_shared_key(NoiseHandshakeState *state, const uint8_t *key, size_t key_len)
Sets the pre shared key for a HandshakeState.
#define NOISE_MAX_HASHLEN
Maximum hash length over all supported hash algorithms.
Definition: internal.h:48
#define NOISE_PAT_FLAG_LOCAL_STATIC
Definition: internal.h:601
int noise_handshakestate_write_message(NoiseHandshakeState *state, NoiseBuffer *message, const NoiseBuffer *payload)
Writes a message payload using a HandshakeState.
int noise_hashstate_hash_one(NoiseHashState *state, const uint8_t *data, size_t data_len, uint8_t *hash, size_t hash_len)
Hashes a single data buffer and returns the hash value.
Definition: hashstate.c:309
#define NOISE_PAT_FLAG_REMOTE_STATIC
Definition: internal.h:619
NoiseSymmetricState * symmetric
Points to the SymmetricState object for this HandshakeState.
Definition: internal.h:549
uint16_t shared_key_len
Length of the shared key for this algorithm in bytes.
Definition: internal.h:240
#define NOISE_ACTION_SPLIT
The HandshakeState has flagged that the handshake is over and that the application is expected to cal...
#define NOISE_TOKEN_F
Definition: internal.h:596
#define NOISE_PAT_FLAG_REMOTE_HYBRID
Definition: internal.h:631
#define NOISE_ERROR_INVALID_PUBLIC_KEY
Invalid public key value.
uint8_t pre_shared_key[NOISE_PSK_LEN]
Pre-shared key value.
Definition: internal.h:576
Internal structure of the NoiseDHState type.
Definition: internal.h:213
NoiseDHState * dh_remote_hybrid
Points to the DHState object for remote hybrid forward secrecy key.
Definition: internal.h:567
#define NOISE_TOKEN_ES
Definition: internal.h:593
#define NOISE_PAT_FLAG_REMOTE_EPHEMERAL
Definition: internal.h:621
NoiseDHState * noise_handshakestate_get_fixed_ephemeral_dh(NoiseHandshakeState *state)
Gets the DHState object that contains the local ephemeral keypair.
#define NOISE_ERROR_NO_MEMORY
Insufficient memory to complete the operation.
#define NOISE_PAT_FLAG_REMOTE_EPHEM_REQ
Definition: internal.h:629
NoiseDHState * noise_handshakestate_get_local_keypair_dh(const NoiseHandshakeState *state)
Gets the DHState object that contains the local static keypair.
int noise_handshakestate_needs_remote_public_key(const NoiseHandshakeState *state)
Determine if a HandshakeState still needs to be configured with a remote public key before the protoc...
#define NOISE_PAT_FLAG_REMOTE_REQUIRED
Definition: internal.h:626
#define NOISE_MAX_PROTOCOL_NAME
Maximum length of a protocol name string.
int action
Next action to be taken by the application.
Definition: internal.h:543
uint64_t n
The nonce value for the next packet.
Definition: internal.h:76
#define NOISE_ERROR_INVALID_LENGTH
Invalid length specified for a key, packet, etc.
int noise_handshakestate_set_prologue(NoiseHandshakeState *state, const void *prologue, size_t prologue_len)
Sets the prologue for a HandshakeState.
uint8_t key_type
The type of key stored within this DHState object.
Definition: internal.h:225
#define NOISE_ACTION_FAILED
The HandshakeState has flagged that the handshake has failed due to some kind of error.
int noise_handshakestate_get_action(const NoiseHandshakeState *state)
Gets the next action the application should perform for the handshake phase of the protocol...
NoiseCipherState * cipher
Points to the CipherState object for this SymmetricState.
Definition: internal.h:516
int noise_symmetricstate_free(NoiseSymmetricState *state)
Frees a SymmetricState object after destroying all sensitive material.
int noise_handshakestate_split(NoiseHandshakeState *state, NoiseCipherState **send, NoiseCipherState **receive)
Splits the transport encryption CipherState objects out of this HandshakeState object.
int noise_dhstate_has_keypair(const NoiseDHState *state)
Determine if a DHState object contains a keypair.
Definition: dhstate.c:247
#define NOISE_ROLE_INITIATOR
This end of the communications is the initiator.
int role
The role of this object, initiator or responder.
Definition: internal.h:537
#define NOISE_TOKEN_FLIP_DIR
Definition: internal.h:598
int noise_dhstate_calculate(const NoiseDHState *private_key_state, const NoiseDHState *public_key_state, uint8_t *shared_key, size_t shared_key_len)
Performs a Diffie-Hellman calculation.
Definition: dhstate.c:686
#define NOISE_ERROR_LOCAL_KEY_REQUIRED
A local keypair is required for the selected protocol, but one was not supplied.
Internal structure of the NoiseSymmetricState type.
Definition: internal.h:500
#define NOISE_TOKEN_END
Definition: internal.h:589
int noise_hashstate_hkdf(NoiseHashState *state, const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *output1, size_t output1_len, uint8_t *output2, size_t output2_len)
Hashes input data with a key to generate two output values.
Definition: hashstate.c:477
size_t noise_symmetricstate_get_mac_length(const NoiseSymmetricState *state)
Gets the current length of packet MAC values for a SymmetricState object.
int noise_symmetricstate_new_by_id(NoiseSymmetricState **state, const NoiseProtocolId *id)
Creates a new SymmetricState object from a protocol identifier.
NoiseDHState * noise_handshakestate_get_remote_public_key_dh(const NoiseHandshakeState *state)
Gets the DHState object that contains the remote static public key.
int noise_symmetricstate_mix_hash(NoiseSymmetricState *state, const uint8_t *input, size_t size)
Mixes new input data into the handshake hash.
#define NOISE_ERROR_NOT_APPLICABLE
An option was supplied that was not applicable to the selected protocol.
int requirements
Requirements that are yet to be satisfied.
Definition: internal.h:540
uint8_t * prologue
Points to the prologue value.
Definition: internal.h:582
Internal definitions for the library.
#define NOISE_ROLE_RESPONDER
This end of the communications is the responder.
int noise_dhstate_free(NoiseDHState *state)
Frees a DHState object after destroying all sensitive material.
Definition: dhstate.c:146
int noise_symmetricstate_encrypt_and_hash(NoiseSymmetricState *state, NoiseBuffer *buffer)
Encrypts a block of data with this SymmetricState object and adds the ciphertext to the handshake has...
#define NOISE_REQ_FALLBACK_POSSIBLE
Definition: internal.h:649
size_t size
Definition: buffer.h:36
void noise_free(void *ptr, size_t size)
Destroys the contents of a block of memory and free it.
Definition: util.c:152
int noise_handshakestate_needs_local_keypair(const NoiseHandshakeState *state)
Determine if a HandshakeState still needs to be configured with a local keypair.
#define NOISE_TOKEN_S
Definition: internal.h:590
#define NOISE_DH_NONE
Diffie-Hellman identifier that indicates "no DH".
#define NOISE_TOKEN_SS
Definition: internal.h:595
size_t pre_shared_key_len
Length of the pre-shared key value: zero or NOISE_PSK_LEN only.
Definition: internal.h:579
Internal structure of the NoiseCipherState type.
Definition: internal.h:58
#define noise_new(type)
Allocates an object from the system and initializes it.
Definition: util.h:35
#define NOISE_ERROR_REMOTE_KEY_REQUIRED
A remote static public key is required for the selected protocol, but one was not supplied...
#define NOISE_PATTERN_NN
Handshake pattern identifier for "NN".
#define NOISE_REQ_REMOTE_REQUIRED
Definition: internal.h:639
NoisePatternFlags_t noise_pattern_reverse_flags(NoisePatternFlags_t flags)
Reverses the local and remote flags for a pattern.
Definition: patterns.c:1306
int(* copy)(NoiseDHState *state, const NoiseDHState *from, const NoiseDHState *other)
Copies another key into this object.
Definition: internal.h:310
int noise_dhstate_has_public_key(const NoiseDHState *state)
Determine if a DHState object contains a public key.
Definition: dhstate.c:267
int noise_handshakestate_fallback_to(NoiseHandshakeState *state, int pattern_id)
Falls back to another handshake pattern.
NoiseDHState * noise_handshakestate_get_fixed_hybrid_dh(NoiseHandshakeState *state)
Gets the DHState object that contains the local additional hybrid secrecy keypair.
#define NOISE_PATTERN_XX_FALLBACK
Handshake pattern identifier for "XXfallback".
const uint8_t * noise_pattern_lookup(int id)
Looks up a specific handshake pattern.
Definition: patterns.c:1253
int noise_handshakestate_has_remote_public_key(const NoiseHandshakeState *state)
Determine if a HandshakeState has a remote public key.
int prefix_id
Definition: names.h:35
int noise_dhstate_is_null_public_key(const NoiseDHState *state)
Determine if the public key in a DHState object has the special null value.
Definition: dhstate.c:602
int noise_handshakestate_new_by_name(NoiseHandshakeState **state, const char *protocol_name, int role)
Creates a new HandshakeState object by protocol name.
#define NOISE_ACTION_READ_MESSAGE
The HandshakeState expects the application to read the next message payload from the handshake...
#define NOISE_TOKEN_SE
Definition: internal.h:594
size_t noise_hashstate_get_hash_length(const NoiseHashState *state)
Gets the length of the hash output for a HashState object.
Definition: hashstate.c:192
#define NOISE_PREFIX_PSK
Protocol prefix identifier for "NoisePSK".
#define NOISE_REQ_FALLBACK_PREMSG
Definition: internal.h:643
#define NOISE_REQ_PSK
Definition: internal.h:641
#define NOISE_PAT_FLAG_LOCAL_HYBRID
Definition: internal.h:613
int noise_protocol_id_to_name(char *name, size_t name_len, const NoiseProtocolId *id)
Formats a protocol name from a set of identifiers for the algorithms that make up the name...
Definition: names.c:437
int noise_handshakestate_start(NoiseHandshakeState *state)
Starts the handshake on a HandshakeState object.
#define NOISE_REQ_LOCAL_REQUIRED
Definition: internal.h:637
#define NOISE_TOKEN_E
Definition: internal.h:591
NoiseDHState * dh_local_hybrid
Points to the DHState object for local hybrid forward secrecy key.
Definition: internal.h:558
short dh_id
Algorithm identifier for the Diffie-Hellman operation.
Definition: internal.h:219
int noise_dhstate_set_public_key(NoiseDHState *state, const uint8_t *public_key, size_t public_key_len)
Sets the public key in a DHState object.
Definition: dhstate.c:511
int noise_dhstate_set_role(NoiseDHState *state, int role)
Sets the role that a DHState object will play in a handshake.
Definition: dhstate.c:835
#define NOISE_PAT_FLAG_LOCAL_EPHEM_REQ
Definition: internal.h:611
#define NOISE_ERROR_PSK_REQUIRED
A pre shared key is required for the selected protocol, but one was not supplied. ...
Internal structure of the NoiseHandshakeState type.
Definition: internal.h:531
NoiseDHState * dh_remote_static
Points to the DHState object for remote static key.
Definition: internal.h:561
int noise_symmetricstate_split(NoiseSymmetricState *state, NoiseCipherState **c1, NoiseCipherState **c2)
Splits the transport encryption CipherState objects out of this SymmetricState object.
int noise_dhstate_generate_dependent_keypair(NoiseDHState *state, const NoiseDHState *other)
Generates a new key pair within a DHState object that may depend upon the parameters from another DHS...
Definition: dhstate.c:332
int hybrid_id
Definition: names.h:40
int noise_symmetricstate_new_by_name(NoiseSymmetricState **state, const char *name)
Creates a new SymmetricState object from a protocol name.
uint8_t * private_key
Points to the private key in the subclass state.
Definition: internal.h:243
short role
The role; either initiator or responder or zero.
Definition: internal.h:222
int noise_symmetricstate_decrypt_and_hash(NoiseSymmetricState *state, NoiseBuffer *buffer)
Decrypts a block of data with this SymmetricState object and adds the ciphertext to the handshake has...
Type that defines a region of memory for a data buffer.
Definition: buffer.h:33
NoiseDHState * dh_local_static
Points to the DHState object for local static key.
Definition: internal.h:552
int noise_handshakestate_has_local_keypair(const NoiseHandshakeState *state)
Determine if a HandshakeState has been configured with a local keypair.
NoiseDHState * dh_fixed_hybrid
Points to the object for the fixed hybrid forward secrecy test key.
Definition: internal.h:573
uint16_t public_key_len
Length of the public key for this algorithm in bytes.
Definition: internal.h:237
#define NOISE_ACTION_WRITE_MESSAGE
The HandshakeState expects the application to write the next message payload for the handshake...
int pattern_id
Definition: names.h:36