1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* plugins/preauth/spake/groups.h - SPAKE group interfaces */ 3 /* 4 * Copyright (C) 2015 by the Massachusetts Institute of Technology. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef GROUPS_H 34 #define GROUPS_H 35 36 #include "k5-int.h" 37 #include "iana.h" 38 39 typedef struct groupstate_st groupstate; 40 typedef struct groupdata_st groupdata; 41 typedef struct groupdef_st groupdef; 42 43 struct groupdef_st { 44 const spake_iana *reg; 45 46 /* 47 * Optional: create a per-group data object to allow more efficient keygen 48 * and result computations. Saving a reference to gdef is okay; its 49 * lifetime will always be longer than the resulting object. 50 */ 51 krb5_error_code (*init)(krb5_context context, const groupdef *gdef, 52 groupdata **gdata_out); 53 54 /* Optional: release a group data object. */ 55 void (*fini)(groupdata *gdata); 56 57 /* 58 * Mandatory: generate a random private scalar (x or y) and a public 59 * element (T or S), using wbytes for the w value. If use_m is true, use 60 * the M element (generating T); otherwise use the N element (generating 61 * S). wbytes and priv_out have length reg->mult_len; pub_out has length 62 * reg->elem_len. priv_out and pub_out are caller-allocated. 63 */ 64 krb5_error_code (*keygen)(krb5_context context, groupdata *gdata, 65 const uint8_t *wbytes, krb5_boolean use_m, 66 uint8_t *priv_out, uint8_t *pub_out); 67 68 /* 69 * Mandatory: compute K given a private scalar (x or y) and the other 70 * party's public element (S or T), using wbytes for the w value. If use_m 71 * is true, use the M element (computing K from y and T); otherwise use the 72 * N element (computing K from x and S). wbytes and ourpriv have length 73 * reg->mult_len; theirpub and elem_out have length reg->elem_len. 74 * elem_out is caller-allocated. 75 */ 76 krb5_error_code (*result)(krb5_context context, groupdata *gdata, 77 const uint8_t *wbytes, const uint8_t *ourpriv, 78 const uint8_t *theirpub, krb5_boolean use_m, 79 uint8_t *elem_out); 80 81 /* 82 * Mandatory: compute the group's specified hash function over datas (with 83 * ndata elements), placing the result in result_out. result_out is 84 * caller-allocated with length reg->hash_len. 85 */ 86 krb5_error_code (*hash)(krb5_context context, groupdata *gdata, 87 const krb5_data *datas, size_t ndata, 88 uint8_t *result_out); 89 }; 90 91 /* Initialize an object which holds group configuration and pre-computation 92 * state for each group. is_kdc is true for KDCs, false for clients. */ 93 krb5_error_code group_init_state(krb5_context context, krb5_boolean is_kdc, 94 groupstate **out); 95 96 /* Release resources held by gstate. */ 97 void group_free_state(groupstate *gstate); 98 99 /* Return true if group is permitted by configuration. */ 100 krb5_boolean group_is_permitted(groupstate *gstate, int32_t group); 101 102 /* Set *list_out and *count_out to the list of groups permitted by 103 * configuration. */ 104 void group_get_permitted(groupstate *gstate, int32_t **list_out, 105 int32_t *count_out); 106 107 /* Return the KDC optimistic challenge group if one is configured. Valid for 108 * KDC groupstate objects only. */ 109 krb5_int32 group_optimistic_challenge(groupstate *gstate); 110 111 /* Set *len_out to the multiplier length for group. */ 112 krb5_error_code group_mult_len(int32_t group, size_t *len_out); 113 114 /* 115 * Generate a SPAKE private scalar (x or y) and public element (T or S), given 116 * an input multiplier wbytes. Use constant M if gstate is a KDC groupstate 117 * object, N if it is a client object. Allocate storage and place the results 118 * in *priv_out and *pub_out. 119 */ 120 krb5_error_code group_keygen(krb5_context context, groupstate *gstate, 121 int32_t group, const krb5_data *wbytes, 122 krb5_data *priv_out, krb5_data *pub_out); 123 124 /* 125 * Compute the SPAKE result K from our private scalar (x or y) and their public 126 * key (S or T), deriving the input scalar w from ikey. Use the other party's 127 * constant, N if gstate is a KDC groupstate object or M if it is a client 128 * object. Allocate storage and place the result in *spakeresult_out. 129 */ 130 krb5_error_code group_result(krb5_context context, groupstate *gstate, 131 int32_t group, const krb5_data *wbytes, 132 const krb5_data *ourpriv, 133 const krb5_data *theirpub, 134 krb5_data *spakeresult_out); 135 136 /* Set *result_out to the hash output length for group. */ 137 krb5_error_code group_hash_len(int32_t group, size_t *result_out); 138 139 /* 140 * Compute the group's specified hash function over dlist (with ndata 141 * elements). result_out is caller-allocated with enough bytes for the hash 142 * output as given by group_hash_len(). 143 */ 144 krb5_error_code group_hash(krb5_context context, groupstate *gstate, 145 int32_t group, const krb5_data *dlist, size_t ndata, 146 uint8_t *result_out); 147 148 #endif /* GROUPS_H */ 149