guile: Fix `priorities' test to use `run-test'.
[gnutls.git] / lib / opencdk / seskey.c
blob5d97aca04b7354e7085f8d34230ebb9f4c4b4781
1 /* seskey.c - Session key routines
2 * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2007, 2008, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Timo Schulz
7 * This file is part of OpenCDK.
9 * The OpenCDK library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <stdio.h>
28 #include "opencdk.h"
29 #include "main.h"
30 #include "packet.h"
33 /* We encode the MD in this way:
35 * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
37 * PAD consists of FF bytes.
39 static cdk_error_t
40 do_encode_md (byte ** r_frame, size_t * r_flen, const byte * md, int algo,
41 size_t len, unsigned nbits, const byte * asn, size_t asnlen)
43 byte *frame = NULL;
44 size_t nframe = (nbits + 7) / 8;
45 ssize_t i;
46 size_t n = 0;
48 if (!asn || !md || !r_frame || !r_flen)
49 return CDK_Inv_Value;
51 if (len + asnlen + 4 > nframe)
52 return CDK_General_Error;
54 frame = cdk_calloc (1, nframe);
55 if (!frame)
56 return CDK_Out_Of_Core;
57 frame[n++] = 0;
58 frame[n++] = 1;
59 i = nframe - len - asnlen - 3;
60 if (i < 0)
62 cdk_free (frame);
63 return CDK_Inv_Value;
65 memset (frame + n, 0xFF, i);
66 n += i;
67 frame[n++] = 0;
68 memcpy (frame + n, asn, asnlen);
69 n += asnlen;
70 memcpy (frame + n, md, len);
71 n += len;
72 if (n != nframe)
74 cdk_free (frame);
75 return CDK_Inv_Value;
77 *r_frame = frame;
78 *r_flen = n;
79 return 0;
82 static const byte md5_asn[18] = /* Object ID is 1.2.840.113549.2.5 */
83 { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
84 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
87 static const byte sha1_asn[15] = /* Object ID is 1.3.14.3.2.26 */
88 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
89 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
92 static const byte sha224_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
93 { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
94 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
95 0x1C
98 static const byte sha256_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
99 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
100 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
101 0x00, 0x04, 0x20
104 static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
106 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
107 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
108 0x00, 0x04, 0x40
111 static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
113 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
114 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
115 0x00, 0x04, 0x30
118 static const byte rmd160_asn[15] = /* Object ID is 1.3.36.3.2.1 */
119 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
120 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
123 static int
124 _gnutls_get_digest_oid (gnutls_digest_algorithm_t algo, const byte ** data)
126 switch (algo)
128 case GNUTLS_DIG_MD5:
129 *data = md5_asn;
130 return sizeof (md5_asn);
131 case GNUTLS_DIG_SHA1:
132 *data = sha1_asn;
133 return sizeof (sha1_asn);
134 case GNUTLS_DIG_RMD160:
135 *data = rmd160_asn;
136 return sizeof (rmd160_asn);
137 case GNUTLS_DIG_SHA256:
138 *data = sha256_asn;
139 return sizeof (sha256_asn);
140 case GNUTLS_DIG_SHA384:
141 *data = sha384_asn;
142 return sizeof (sha384_asn);
143 case GNUTLS_DIG_SHA512:
144 *data = sha512_asn;
145 return sizeof (sha512_asn);
146 case GNUTLS_DIG_SHA224:
147 *data = sha224_asn;
148 return sizeof (sha224_asn);
149 default:
150 gnutls_assert ();
151 return GNUTLS_E_INTERNAL_ERROR;
156 /* Encode the given digest into a pkcs#1 compatible format. */
157 cdk_error_t
158 _cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen, int pk_algo,
159 const byte * md, int digest_algo, unsigned nbits)
161 size_t dlen;
163 if (!md || !r_md || !r_mdlen)
164 return CDK_Inv_Value;
166 dlen = _gnutls_hash_get_algo_len (digest_algo);
167 if (dlen <= 0)
168 return CDK_Inv_Algo;
169 if (is_DSA (pk_algo))
170 { /* DSS does not use a special encoding. */
171 *r_md = cdk_malloc (dlen + 1);
172 if (!*r_md)
173 return CDK_Out_Of_Core;
174 *r_mdlen = dlen;
175 memcpy (*r_md, md, dlen);
176 return 0;
178 else
180 const byte *asn;
181 int asnlen;
182 cdk_error_t rc;
184 asnlen = _gnutls_get_digest_oid (digest_algo, &asn);
185 if (asnlen < 0)
186 return asnlen;
188 rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen,
189 nbits, asn, asnlen);
190 return rc;
192 return 0;
197 * cdk_s2k_new:
198 * @ret_s2k: output for the new S2K object
199 * @mode: the S2K mode (simple, salted, iter+salted)
200 * @digest_algo: the hash algorithm
201 * @salt: random salt
203 * Create a new S2K object with the given parameter.
204 * The @salt parameter must be always 8 octets.
206 cdk_error_t
207 cdk_s2k_new (cdk_s2k_t * ret_s2k, int mode, int digest_algo,
208 const byte * salt)
210 cdk_s2k_t s2k;
212 if (!ret_s2k)
213 return CDK_Inv_Value;
215 if (mode != 0x00 && mode != 0x01 && mode != 0x03)
216 return CDK_Inv_Mode;
218 if (_gnutls_hash_get_algo_len (digest_algo) <= 0)
219 return CDK_Inv_Algo;
221 s2k = cdk_calloc (1, sizeof *s2k);
222 if (!s2k)
223 return CDK_Out_Of_Core;
224 s2k->mode = mode;
225 s2k->hash_algo = digest_algo;
226 if (salt)
227 memcpy (s2k->salt, salt, 8);
228 *ret_s2k = s2k;
229 return 0;
234 * cdk_s2k_free:
235 * @s2k: the S2K object
237 * Release the given S2K object.
239 void
240 cdk_s2k_free (cdk_s2k_t s2k)
242 cdk_free (s2k);
246 /* Make a copy of the source s2k into R_DST. */
247 cdk_error_t
248 _cdk_s2k_copy (cdk_s2k_t * r_dst, cdk_s2k_t src)
250 cdk_s2k_t dst;
251 cdk_error_t err;
253 err = cdk_s2k_new (&dst, src->mode, src->hash_algo, src->salt);
254 if (err)
255 return err;
256 dst->count = src->count;
257 *r_dst = dst;
259 return 0;