mirror of
				https://git.proxmox.com/git/grub2
				synced 2025-10-31 17:40:15 +00:00 
			
		
		
		
	 47e67d809c
			
		
	
	
		47e67d809c
		
	
	
	
	
		
			
			-Wunreachable-code has been a no-op since GCC 4.5; GRUB hasn't been compiled with it since 2012; and GCC 6 produces "error: '-Wunreachable-code' is not an option that controls warnings" for these. Fixes Debian bug #812047.
		
			
				
	
	
		
			110 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5
 | |
|    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; either version 2, or (at your option)
 | |
|    any later version.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software Foundation,
 | |
|    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 | |
| 
 | |
| /* Written by Simon Josefsson.  */
 | |
| /* Imported from gnulib.  */
 | |
| 
 | |
| #include <grub/crypto.h>
 | |
| #include <grub/mm.h>
 | |
| #include <grub/misc.h>
 | |
| #include <grub/dl.h>
 | |
| 
 | |
| GRUB_MOD_LICENSE ("GPLv2+");
 | |
| 
 | |
| /* Implement PKCS#5 PBKDF2 as per RFC 2898.  The PRF to use is HMAC variant
 | |
|    of digest supplied by MD.  Inputs are the password P of length PLEN,
 | |
|    the salt S of length SLEN, the iteration counter C (> 0), and the
 | |
|    desired derived output length DKLEN.  Output buffer is DK which
 | |
|    must have room for at least DKLEN octets.  The output buffer will
 | |
|    be filled with the derived data.  */
 | |
| 
 | |
| gcry_err_code_t
 | |
| grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
 | |
| 		    const grub_uint8_t *P, grub_size_t Plen,
 | |
| 		    const grub_uint8_t *S, grub_size_t Slen,
 | |
| 		    unsigned int c,
 | |
| 		    grub_uint8_t *DK, grub_size_t dkLen)
 | |
| {
 | |
|   unsigned int hLen = md->mdlen;
 | |
|   grub_uint8_t U[GRUB_CRYPTO_MAX_MDLEN];
 | |
|   grub_uint8_t T[GRUB_CRYPTO_MAX_MDLEN];
 | |
|   unsigned int u;
 | |
|   unsigned int l;
 | |
|   unsigned int r;
 | |
|   unsigned int i;
 | |
|   unsigned int k;
 | |
|   gcry_err_code_t rc;
 | |
|   grub_uint8_t *tmp;
 | |
|   grub_size_t tmplen = Slen + 4;
 | |
| 
 | |
|   if (md->mdlen > GRUB_CRYPTO_MAX_MDLEN || md->mdlen == 0)
 | |
|     return GPG_ERR_INV_ARG;
 | |
| 
 | |
|   if (c == 0)
 | |
|     return GPG_ERR_INV_ARG;
 | |
| 
 | |
|   if (dkLen == 0)
 | |
|     return GPG_ERR_INV_ARG;
 | |
| 
 | |
|   if (dkLen > 4294967295U)
 | |
|     return GPG_ERR_INV_ARG;
 | |
| 
 | |
|   l = ((dkLen - 1) / hLen) + 1;
 | |
|   r = dkLen - (l - 1) * hLen;
 | |
| 
 | |
|   tmp = grub_malloc (tmplen);
 | |
|   if (tmp == NULL)
 | |
|     return GPG_ERR_OUT_OF_MEMORY;
 | |
| 
 | |
|   grub_memcpy (tmp, S, Slen);
 | |
| 
 | |
|   for (i = 1; i - 1 < l; i++)
 | |
|     {
 | |
|       grub_memset (T, 0, hLen);
 | |
| 
 | |
|       for (u = 0; u < c; u++)
 | |
| 	{
 | |
| 	  if (u == 0)
 | |
| 	    {
 | |
| 	      tmp[Slen + 0] = (i & 0xff000000) >> 24;
 | |
| 	      tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
 | |
| 	      tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
 | |
| 	      tmp[Slen + 3] = (i & 0x000000ff) >> 0;
 | |
| 
 | |
| 	      rc = grub_crypto_hmac_buffer (md, P, Plen, tmp, tmplen, U);
 | |
| 	    }
 | |
| 	  else
 | |
| 	    rc = grub_crypto_hmac_buffer (md, P, Plen, U, hLen, U);
 | |
| 
 | |
| 	  if (rc != GPG_ERR_NO_ERROR)
 | |
| 	    {
 | |
| 	      grub_free (tmp);
 | |
| 	      return rc;
 | |
| 	    }
 | |
| 
 | |
| 	  for (k = 0; k < hLen; k++)
 | |
| 	    T[k] ^= U[k];
 | |
| 	}
 | |
| 
 | |
|       grub_memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
 | |
|     }
 | |
| 
 | |
|   grub_free (tmp);
 | |
| 
 | |
|   return GPG_ERR_NO_ERROR;
 | |
| }
 |