Initial revision
[silc.git] / lib / silcske / groups.c
1 /*
2
3   groups.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 2000 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * $Id$
22  * $Log$
23  * Revision 1.1  2000/06/27 11:36:56  priikone
24  * Initial revision
25  *
26  *
27  */
28
29 #include "silcincludes.h"
30 #include "groups_internal.h"
31
32 /* Fixed and public Diffie Hellman Groups defined by the SKE
33    protocol. These are equivalent to the OAKLEY Key Determination
34    protocol groups (taken from RFC 2412). */
35 const struct SilcSKEDiffieHellmanGroupDefStruct silc_ske_groups[] = 
36 {
37   /* 1024 bits modulus (Mandatory group) */
38   { 1, "diffie-hellman-group1",
39     "0x"
40     "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1"
41     "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD"
42     "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245"
43     "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED"
44     "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381"
45     "FFFFFFFF FFFFFFFF",
46     "0x"
47     "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68"
48     "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E"
49     "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122"
50     "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6"
51     "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F67329C0"
52     "FFFFFFFF FFFFFFFF",
53     "0x2" },
54
55   /* 1536 bits modulus (Optional group) */
56   { 2, "diffie-hellman-group2",
57     "0x"
58     "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1"
59     "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD"
60     "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245"
61     "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED"
62     "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D"
63     "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F"
64     "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D"
65     "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF",
66     "0x"
67     "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68"
68     "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E"
69     "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122"
70     "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6"
71     "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F6722D9E"
72     "E1003E5C 50B1DF82 CC6D241B 0E2AE9CD 348B1FD4 7E9267AF"
73     "C1B2AE91 EE51D6CB 0E3179AB 1042A95D CF6A9483 B84B4B36"
74     "B3861AA7 255E4C02 78BA3604 6511B993 FFFFFFFF FFFFFFFF",
75     "0x2" },
76
77   { 0, NULL, NULL, NULL }
78 };
79
80 /* Returns Diffie Hellman group by group number */
81
82 SilcSKEStatus silc_ske_get_group_by_number(int number,
83                                            SilcSKEDiffieHellmanGroup *ret)
84 {
85   int i;
86   SilcSKEDiffieHellmanGroup group;
87
88   for (i = 0; silc_ske_groups[i].name; i++) {
89     if (silc_ske_groups[i].number == number)
90       break;
91   }
92
93   if (silc_ske_groups[i].name == NULL)
94     return SILC_SKE_STATUS_UNKNOWN_GROUP;
95
96   /* Return the group */
97   if (ret) {
98     group = silc_calloc(1, sizeof(*group));
99     group->number = number;
100     group->name = silc_ske_groups[i].name;
101     silc_mp_init(&group->group);
102     silc_mp_init(&group->group_order);
103     silc_mp_init(&group->generator);
104     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 0);
105     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 0);
106     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 0);
107     
108     *ret = group;
109   }
110
111   return SILC_SKE_STATUS_OK;
112 }
113
114 /* Returns Diffie Hellman group by name */
115
116 SilcSKEStatus silc_ske_get_group_by_name(const char *name,
117                                          SilcSKEDiffieHellmanGroup *ret)
118 {
119   int i;
120   SilcSKEDiffieHellmanGroup group;
121
122   for (i = 0; silc_ske_groups[i].name; i++) {
123     if (!strcmp(silc_ske_groups[i].name, name))
124       break;
125   }
126
127   if (silc_ske_groups[i].name == NULL)
128     return SILC_SKE_STATUS_UNKNOWN_GROUP;
129
130   /* Return the group */
131   if (ret) {
132     group = silc_calloc(1, sizeof(*group));
133     group->number = silc_ske_groups[i].number;
134     group->name = silc_ske_groups[i].name;
135     silc_mp_init(&group->group);
136     silc_mp_init(&group->group_order);
137     silc_mp_init(&group->generator);
138     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 0);
139     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 0);
140     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 0);
141     
142     *ret = group;
143   }
144
145   return SILC_SKE_STATUS_OK;
146 }
147
148 /* Returns comma separated list of supported groups */
149
150 char *silc_ske_get_supported_groups()
151 {
152   char *list = NULL;
153   int i, len;
154
155   len = 0;
156   for (i = 0; silc_ske_groups[i].name; i++) {
157     len += strlen(silc_ske_groups[i].name);
158     list = silc_realloc(list, len + 1);
159
160     memcpy(list + (len - strlen(silc_ske_groups[i].name)), 
161            silc_ske_groups[i].name, strlen(silc_ske_groups[i].name));
162     memcpy(list + len, ",", 1);
163     len++;
164   }
165
166   list[len - 1] = 0;
167
168   return list;
169 }