File: sha-crypt.c

package info (click to toggle)
libxcrypt 2.3-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,652 kB
  • ctags: 286
  • sloc: sh: 8,400; ansic: 2,905; makefile: 96
file content (100 lines) | stat: -rw-r--r-- 2,247 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "xcrypt-private.h"
#include "xcrypt.h"

#define SHA_DIGESTSIZE 20

/* Define our magic string to mark salt for SHA1 "encryption"
   replacement.  */
const char *sha_salt_prefix = "{SHA}";

/* Table with characters for base64 transformation.  */
static const char *b64 =
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static int
base64encode (char *encoded, const unsigned char *string, int len)
{
  int i;
  char *p;

  p = encoded;
  for (i = 0; i < len - 2; i += 3)
    {
      *p++ = b64[(string[i] >> 2) & 0x3F];
      *p++ = b64[((string[i] & 0x3) << 4) |
		 ((int) (string[i + 1] & 0xF0) >> 4)];
      *p++ = b64[((string[i + 1] & 0xF) << 2) |
		 ((int) (string[i + 2] & 0xC0) >> 6)];
      *p++ = b64[string[i + 2] & 0x3F];
    }
  if (i < len)
    {
      *p++ = b64[(string[i] >> 2) & 0x3F];
      if (i == (len - 1))
	{
	  *p++ = b64[((string[i] & 0x3) << 4)];
	  *p++ = '=';
	}
      else
	{
	  *p++ = b64[((string[i] & 0x3) << 4) |
		     ((int) (string[i + 1] & 0xF0) >> 4)];
	  *p++ = b64[((string[i + 1] & 0xF) << 2)];
	}
      *p++ = '=';
    }

  *p++ = '\0';
  return p - encoded;
}


/* This entry point is equivalent to the `crypt' function in Unix
   libcs. SHA1 ignores salt.  */
char *
__sha_crypt_r (const char *key, const char *salt __attribute__ ((unused)),
	       char *buffer, int buflen)
{
  SHA1_CTX c;
  unsigned char md[SHA_DIGESTSIZE];
  int l;

  if (buflen < (SHA_DIGESTSIZE + 8 + sizeof (sha_salt_prefix)))
    {
      errno = ERANGE;
      return NULL;
    }

  memset (md, 0, SHA_DIGESTSIZE);

  __SHA1Init (&c);
  __SHA1Update (&c, key, strlen (key));
  __SHA1Final (md, &c);

  memcpy (buffer, sha_salt_prefix, sizeof (sha_salt_prefix));

  l = base64encode (&buffer[sizeof sha_salt_prefix], md, sizeof (md));
  buffer[l + strlen (sha_salt_prefix)] = '\0';

  return buffer;
}


char *
__sha_crypt (const char *key, const char *salt)
{
  static char buffer[SHA_DIGESTSIZE + 8 + sizeof (sha_salt_prefix)];
  static int buflen = sizeof (buffer);

  return __sha_crypt_r (key, salt, buffer, buflen);
}

#undef sha_crypt
#undef sha_crypt_r
weak_alias (__sha_crypt, sha_crypt)
weak_alias (__sha_crypt_r, sha_crypt_r)