pkcs5.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /**
  2. * \file pkcs5.c
  3. *
  4. * \brief PKCS#5 functions
  5. *
  6. * \author Mathias Olsson <mathias@kompetensum.com>
  7. *
  8. * Copyright The Mbed TLS Contributors
  9. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  10. *
  11. * This file is provided under the Apache License 2.0, or the
  12. * GNU General Public License v2.0 or later.
  13. *
  14. * **********
  15. * Apache License 2.0:
  16. *
  17. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  18. * not use this file except in compliance with the License.
  19. * You may obtain a copy of the License at
  20. *
  21. * http://www.apache.org/licenses/LICENSE-2.0
  22. *
  23. * Unless required by applicable law or agreed to in writing, software
  24. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  25. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  26. * See the License for the specific language governing permissions and
  27. * limitations under the License.
  28. *
  29. * **********
  30. *
  31. * **********
  32. * GNU General Public License v2.0 or later:
  33. *
  34. * This program is free software; you can redistribute it and/or modify
  35. * it under the terms of the GNU General Public License as published by
  36. * the Free Software Foundation; either version 2 of the License, or
  37. * (at your option) any later version.
  38. *
  39. * This program is distributed in the hope that it will be useful,
  40. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  41. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42. * GNU General Public License for more details.
  43. *
  44. * You should have received a copy of the GNU General Public License along
  45. * with this program; if not, write to the Free Software Foundation, Inc.,
  46. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  47. *
  48. * **********
  49. */
  50. /*
  51. * PKCS#5 includes PBKDF2 and more
  52. *
  53. * http://tools.ietf.org/html/rfc2898 (Specification)
  54. * http://tools.ietf.org/html/rfc6070 (Test vectors)
  55. */
  56. #if !defined(MBEDTLS_CONFIG_FILE)
  57. #include "mbedtls/config.h"
  58. #else
  59. #include MBEDTLS_CONFIG_FILE
  60. #endif
  61. #if defined(MBEDTLS_PKCS5_C)
  62. #include "mbedtls/pkcs5.h"
  63. #if defined(MBEDTLS_ASN1_PARSE_C)
  64. #include "mbedtls/asn1.h"
  65. #include "mbedtls/cipher.h"
  66. #include "mbedtls/oid.h"
  67. #endif /* MBEDTLS_ASN1_PARSE_C */
  68. #include <string.h>
  69. #if defined(MBEDTLS_PLATFORM_C)
  70. #include "mbedtls/platform.h"
  71. #else
  72. #include <stdio.h>
  73. #define mbedtls_printf printf
  74. #endif
  75. #if defined(MBEDTLS_ASN1_PARSE_C)
  76. static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
  77. mbedtls_asn1_buf *salt, int *iterations,
  78. int *keylen, mbedtls_md_type_t *md_type )
  79. {
  80. int ret;
  81. mbedtls_asn1_buf prf_alg_oid;
  82. unsigned char *p = params->p;
  83. const unsigned char *end = params->p + params->len;
  84. if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
  85. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
  86. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  87. /*
  88. * PBKDF2-params ::= SEQUENCE {
  89. * salt OCTET STRING,
  90. * iterationCount INTEGER,
  91. * keyLength INTEGER OPTIONAL
  92. * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1
  93. * }
  94. *
  95. */
  96. if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
  97. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  98. salt->p = p;
  99. p += salt->len;
  100. if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
  101. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  102. if( p == end )
  103. return( 0 );
  104. if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
  105. {
  106. if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
  107. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  108. }
  109. if( p == end )
  110. return( 0 );
  111. if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
  112. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  113. if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
  114. return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
  115. if( p != end )
  116. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
  117. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
  118. return( 0 );
  119. }
  120. int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
  121. const unsigned char *pwd, size_t pwdlen,
  122. const unsigned char *data, size_t datalen,
  123. unsigned char *output )
  124. {
  125. int ret, iterations = 0, keylen = 0;
  126. unsigned char *p, *end;
  127. mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params;
  128. mbedtls_asn1_buf salt;
  129. mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1;
  130. unsigned char key[32], iv[32];
  131. size_t olen = 0;
  132. const mbedtls_md_info_t *md_info;
  133. const mbedtls_cipher_info_t *cipher_info;
  134. mbedtls_md_context_t md_ctx;
  135. mbedtls_cipher_type_t cipher_alg;
  136. mbedtls_cipher_context_t cipher_ctx;
  137. p = pbe_params->p;
  138. end = p + pbe_params->len;
  139. /*
  140. * PBES2-params ::= SEQUENCE {
  141. * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
  142. * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
  143. * }
  144. */
  145. if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
  146. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
  147. MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
  148. if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
  149. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  150. // Only PBKDF2 supported at the moment
  151. //
  152. if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 )
  153. return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
  154. if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params,
  155. &salt, &iterations, &keylen,
  156. &md_type ) ) != 0 )
  157. {
  158. return( ret );
  159. }
  160. md_info = mbedtls_md_info_from_type( md_type );
  161. if( md_info == NULL )
  162. return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
  163. if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
  164. &enc_scheme_params ) ) != 0 )
  165. {
  166. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
  167. }
  168. if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
  169. return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
  170. cipher_info = mbedtls_cipher_info_from_type( cipher_alg );
  171. if( cipher_info == NULL )
  172. return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
  173. /*
  174. * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored
  175. * since it is optional and we don't know if it was set or not
  176. */
  177. keylen = cipher_info->key_bitlen / 8;
  178. if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING ||
  179. enc_scheme_params.len != cipher_info->iv_size )
  180. {
  181. return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT );
  182. }
  183. mbedtls_md_init( &md_ctx );
  184. mbedtls_cipher_init( &cipher_ctx );
  185. memcpy( iv, enc_scheme_params.p, enc_scheme_params.len );
  186. if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
  187. goto exit;
  188. if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
  189. iterations, keylen, key ) ) != 0 )
  190. {
  191. goto exit;
  192. }
  193. if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
  194. goto exit;
  195. if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
  196. goto exit;
  197. if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
  198. data, datalen, output, &olen ) ) != 0 )
  199. ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH;
  200. exit:
  201. mbedtls_md_free( &md_ctx );
  202. mbedtls_cipher_free( &cipher_ctx );
  203. return( ret );
  204. }
  205. #endif /* MBEDTLS_ASN1_PARSE_C */
  206. int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
  207. size_t plen, const unsigned char *salt, size_t slen,
  208. unsigned int iteration_count,
  209. uint32_t key_length, unsigned char *output )
  210. {
  211. int ret = 0, j;
  212. unsigned int i;
  213. unsigned char md1[MBEDTLS_MD_MAX_SIZE];
  214. unsigned char work[MBEDTLS_MD_MAX_SIZE];
  215. unsigned char md_size = mbedtls_md_get_size( ctx->md_info );
  216. size_t use_len;
  217. unsigned char *out_p = output;
  218. unsigned char counter[4];
  219. memset( counter, 0, 4 );
  220. counter[3] = 1;
  221. #if UINT_MAX > 0xFFFFFFFF
  222. if( iteration_count > 0xFFFFFFFF )
  223. return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
  224. #endif
  225. while( key_length )
  226. {
  227. // U1 ends up in work
  228. //
  229. if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
  230. goto cleanup;
  231. if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
  232. goto cleanup;
  233. if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 )
  234. goto cleanup;
  235. if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
  236. goto cleanup;
  237. memcpy( md1, work, md_size );
  238. for( i = 1; i < iteration_count; i++ )
  239. {
  240. // U2 ends up in md1
  241. //
  242. if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
  243. goto cleanup;
  244. if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
  245. goto cleanup;
  246. if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
  247. goto cleanup;
  248. // U1 xor U2
  249. //
  250. for( j = 0; j < md_size; j++ )
  251. work[j] ^= md1[j];
  252. }
  253. use_len = ( key_length < md_size ) ? key_length : md_size;
  254. memcpy( out_p, work, use_len );
  255. key_length -= (uint32_t) use_len;
  256. out_p += use_len;
  257. for( i = 4; i > 0; i-- )
  258. if( ++counter[i - 1] != 0 )
  259. break;
  260. }
  261. cleanup:
  262. /* Zeroise buffers to clear sensitive data from memory. */
  263. mbedtls_platform_zeroize( work, MBEDTLS_MD_MAX_SIZE );
  264. mbedtls_platform_zeroize( md1, MBEDTLS_MD_MAX_SIZE );
  265. return( ret );
  266. }
  267. #if defined(MBEDTLS_SELF_TEST)
  268. #if !defined(MBEDTLS_SHA1_C)
  269. int mbedtls_pkcs5_self_test( int verbose )
  270. {
  271. if( verbose != 0 )
  272. mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" );
  273. return( 0 );
  274. }
  275. #else
  276. #define MAX_TESTS 6
  277. static const size_t plen[MAX_TESTS] =
  278. { 8, 8, 8, 24, 9 };
  279. static const unsigned char password[MAX_TESTS][32] =
  280. {
  281. "password",
  282. "password",
  283. "password",
  284. "passwordPASSWORDpassword",
  285. "pass\0word",
  286. };
  287. static const size_t slen[MAX_TESTS] =
  288. { 4, 4, 4, 36, 5 };
  289. static const unsigned char salt[MAX_TESTS][40] =
  290. {
  291. "salt",
  292. "salt",
  293. "salt",
  294. "saltSALTsaltSALTsaltSALTsaltSALTsalt",
  295. "sa\0lt",
  296. };
  297. static const uint32_t it_cnt[MAX_TESTS] =
  298. { 1, 2, 4096, 4096, 4096 };
  299. static const uint32_t key_len[MAX_TESTS] =
  300. { 20, 20, 20, 25, 16 };
  301. static const unsigned char result_key[MAX_TESTS][32] =
  302. {
  303. { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
  304. 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
  305. 0x2f, 0xe0, 0x37, 0xa6 },
  306. { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
  307. 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
  308. 0xd8, 0xde, 0x89, 0x57 },
  309. { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
  310. 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
  311. 0x65, 0xa4, 0x29, 0xc1 },
  312. { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
  313. 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
  314. 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
  315. 0x38 },
  316. { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
  317. 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 },
  318. };
  319. int mbedtls_pkcs5_self_test( int verbose )
  320. {
  321. mbedtls_md_context_t sha1_ctx;
  322. const mbedtls_md_info_t *info_sha1;
  323. int ret, i;
  324. unsigned char key[64];
  325. mbedtls_md_init( &sha1_ctx );
  326. info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 );
  327. if( info_sha1 == NULL )
  328. {
  329. ret = 1;
  330. goto exit;
  331. }
  332. if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 )
  333. {
  334. ret = 1;
  335. goto exit;
  336. }
  337. for( i = 0; i < MAX_TESTS; i++ )
  338. {
  339. if( verbose != 0 )
  340. mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
  341. ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
  342. slen[i], it_cnt[i], key_len[i], key );
  343. if( ret != 0 ||
  344. memcmp( result_key[i], key, key_len[i] ) != 0 )
  345. {
  346. if( verbose != 0 )
  347. mbedtls_printf( "failed\n" );
  348. ret = 1;
  349. goto exit;
  350. }
  351. if( verbose != 0 )
  352. mbedtls_printf( "passed\n" );
  353. }
  354. if( verbose != 0 )
  355. mbedtls_printf( "\n" );
  356. exit:
  357. mbedtls_md_free( &sha1_ctx );
  358. return( ret );
  359. }
  360. #endif /* MBEDTLS_SHA1_C */
  361. #endif /* MBEDTLS_SELF_TEST */
  362. #endif /* MBEDTLS_PKCS5_C */