xref: /freebsd/crypto/krb5/src/plugins/preauth/spake/groups.h (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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