1 /* seskey.c - Session key routines
2 * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2007, 2008, 2010 Free
3 * Software Foundation, Inc.
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 2.1 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
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
35 /* We encode the MD in this way:
37 * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
39 * PAD consists of FF bytes.
42 do_encode_md (byte ** r_frame, size_t * r_flen, const byte * md, int algo,
43 size_t len, unsigned nbits, const byte * asn, size_t asnlen)
46 size_t nframe = (nbits + 7) / 8;
50 if (!asn || !md || !r_frame || !r_flen)
53 if (len + asnlen + 4 > nframe)
54 return CDK_General_Error;
56 frame = cdk_calloc (1, nframe);
58 return CDK_Out_Of_Core;
61 i = nframe - len - asnlen - 3;
67 memset (frame + n, 0xFF, i);
70 memcpy (frame + n, asn, asnlen);
72 memcpy (frame + n, md, len);
84 static const byte md5_asn[18] = /* Object ID is 1.2.840.113549.2.5 */
85 { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
86 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
89 static const byte sha1_asn[15] = /* Object ID is 1.3.14.3.2.26 */
90 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
91 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
94 static const byte sha224_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
95 { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
96 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
100 static const byte sha256_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
101 { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
102 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
106 static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
108 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
109 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
113 static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
115 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
116 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
120 static const byte rmd160_asn[15] = /* Object ID is 1.3.36.3.2.1 */
121 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
122 0x02, 0x01, 0x05, 0x00, 0x04, 0x14
126 _gnutls_get_digest_oid (gnutls_digest_algorithm_t algo, const byte ** data)
132 return sizeof (md5_asn);
133 case GNUTLS_DIG_SHA1:
135 return sizeof (sha1_asn);
136 case GNUTLS_DIG_RMD160:
138 return sizeof (rmd160_asn);
139 case GNUTLS_DIG_SHA256:
141 return sizeof (sha256_asn);
142 case GNUTLS_DIG_SHA384:
144 return sizeof (sha384_asn);
145 case GNUTLS_DIG_SHA512:
147 return sizeof (sha512_asn);
148 case GNUTLS_DIG_SHA224:
150 return sizeof (sha224_asn);
153 return GNUTLS_E_INTERNAL_ERROR;
158 /* Encode the given digest into a pkcs#1 compatible format. */
160 _cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen, int pk_algo,
161 const byte * md, int digest_algo, unsigned nbits)
165 if (!md || !r_md || !r_mdlen)
166 return CDK_Inv_Value;
168 dlen = _gnutls_hash_get_algo_len (digest_algo);
171 if (is_DSA (pk_algo))
172 { /* DSS does not use a special encoding. */
173 *r_md = cdk_malloc (dlen + 1);
175 return CDK_Out_Of_Core;
177 memcpy (*r_md, md, dlen);
186 asnlen = _gnutls_get_digest_oid (digest_algo, &asn);
190 rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen,
200 * @ret_s2k: output for the new S2K object
201 * @mode: the S2K mode (simple, salted, iter+salted)
202 * @digest_algo: the hash algorithm
205 * Create a new S2K object with the given parameter.
206 * The @salt parameter must be always 8 octets.
209 cdk_s2k_new (cdk_s2k_t * ret_s2k, int mode, int digest_algo,
215 return CDK_Inv_Value;
217 if (mode != 0x00 && mode != 0x01 && mode != 0x03)
220 if (_gnutls_hash_get_algo_len (digest_algo) <= 0)
223 s2k = cdk_calloc (1, sizeof *s2k);
225 return CDK_Out_Of_Core;
227 s2k->hash_algo = digest_algo;
229 memcpy (s2k->salt, salt, 8);
237 * @s2k: the S2K object
239 * Release the given S2K object.
242 cdk_s2k_free (cdk_s2k_t s2k)
248 /* Make a copy of the source s2k into R_DST. */
250 _cdk_s2k_copy (cdk_s2k_t * r_dst, cdk_s2k_t src)
255 err = cdk_s2k_new (&dst, src->mode, src->hash_algo, src->salt);
258 dst->count = src->count;