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 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/>
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.
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
)
44 size_t nframe
= (nbits
+ 7) / 8;
48 if (!asn
|| !md
|| !r_frame
|| !r_flen
)
51 if (len
+ asnlen
+ 4 > nframe
)
52 return CDK_General_Error
;
54 frame
= cdk_calloc (1, nframe
);
56 return CDK_Out_Of_Core
;
59 i
= nframe
- len
- asnlen
- 3;
65 memset (frame
+ n
, 0xFF, i
);
68 memcpy (frame
+ n
, asn
, asnlen
);
70 memcpy (frame
+ n
, md
, len
);
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,
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,
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,
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,
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
124 _gnutls_get_digest_oid (gnutls_digest_algorithm_t algo
, const byte
** data
)
130 return sizeof (md5_asn
);
131 case GNUTLS_DIG_SHA1
:
133 return sizeof (sha1_asn
);
134 case GNUTLS_DIG_RMD160
:
136 return sizeof (rmd160_asn
);
137 case GNUTLS_DIG_SHA256
:
139 return sizeof (sha256_asn
);
140 case GNUTLS_DIG_SHA384
:
142 return sizeof (sha384_asn
);
143 case GNUTLS_DIG_SHA512
:
145 return sizeof (sha512_asn
);
146 case GNUTLS_DIG_SHA224
:
148 return sizeof (sha224_asn
);
151 return GNUTLS_E_INTERNAL_ERROR
;
156 /* Encode the given digest into a pkcs#1 compatible format. */
158 _cdk_digest_encode_pkcs1 (byte
** r_md
, size_t * r_mdlen
, int pk_algo
,
159 const byte
* md
, int digest_algo
, unsigned nbits
)
163 if (!md
|| !r_md
|| !r_mdlen
)
164 return CDK_Inv_Value
;
166 dlen
= _gnutls_hash_get_algo_len (digest_algo
);
169 if (is_DSA (pk_algo
))
170 { /* DSS does not use a special encoding. */
171 *r_md
= cdk_malloc (dlen
+ 1);
173 return CDK_Out_Of_Core
;
175 memcpy (*r_md
, md
, dlen
);
184 asnlen
= _gnutls_get_digest_oid (digest_algo
, &asn
);
188 rc
= do_encode_md (r_md
, r_mdlen
, md
, digest_algo
, dlen
,
198 * @ret_s2k: output for the new S2K object
199 * @mode: the S2K mode (simple, salted, iter+salted)
200 * @digest_algo: the hash algorithm
203 * Create a new S2K object with the given parameter.
204 * The @salt parameter must be always 8 octets.
207 cdk_s2k_new (cdk_s2k_t
* ret_s2k
, int mode
, int digest_algo
,
213 return CDK_Inv_Value
;
215 if (mode
!= 0x00 && mode
!= 0x01 && mode
!= 0x03)
218 if (_gnutls_hash_get_algo_len (digest_algo
) <= 0)
221 s2k
= cdk_calloc (1, sizeof *s2k
);
223 return CDK_Out_Of_Core
;
225 s2k
->hash_algo
= digest_algo
;
227 memcpy (s2k
->salt
, salt
, 8);
235 * @s2k: the S2K object
237 * Release the given S2K object.
240 cdk_s2k_free (cdk_s2k_t s2k
)
246 /* Make a copy of the source s2k into R_DST. */
248 _cdk_s2k_copy (cdk_s2k_t
* r_dst
, cdk_s2k_t src
)
253 err
= cdk_s2k_new (&dst
, src
->mode
, src
->hash_algo
, src
->salt
);
256 dst
->count
= src
->count
;