summaryrefslogtreecommitdiffstats
path: root/lib/libskey/skeysubr.c
blob: 3230c31647e39c55e4f459ce8287cdaef87e817a (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* $FreeBSD$ */

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>

#include "skey.h"
#include "mdx.h"

/* Crunch a key:
 * concatenate the seed and the password, run through MDX and
 * collapse to 64 bits. This is defined as the user's starting key.
 */
int
keycrunch(result,seed,passwd)
char *result;   /* 8-byte result */
const char *seed;     /* Seed, any length */
const char *passwd;   /* Password, any length */
{
	char *buf;
	MDX_CTX md;
	u_int32_t results[4];
	unsigned int buflen;

	buflen = strlen(seed) + strlen(passwd);
	if((buf = malloc(buflen+1)) == NULL)
		return -1;
	strcpy(buf,seed);
	strcat(buf,passwd);

	/* Crunch the key through MD[45] */
	sevenbit(buf);
	MDXInit(&md);
	MDXUpdate(&md,(unsigned char *)buf,buflen);
	MDXFinal((unsigned char *)results,&md);
	free(buf);

	results[0] ^= results[2];
	results[1] ^= results[3];

	memcpy(result,(char *)results,8);

	return 0;
}

/* The one-way function f(). Takes 8 bytes and returns 8 bytes in place */
void
f(x)
char *x;
{
	MDX_CTX md;
	u_int32_t results[4];

	MDXInit(&md);
	MDXUpdate(&md,(unsigned char *)x,8);
	MDXFinal((unsigned char *)results,&md);
	/* Fold 128 to 64 bits */
	results[0] ^= results[2];
	results[1] ^= results[3];

	memcpy(x,(char *)results,8);
}

/* Strip trailing cr/lf from a line of text */
void
rip(buf)
char *buf;
{
	buf[strcspn(buf, "\r\n")] = 0;
}

static struct termios saved_ttymode;

static void interrupt __P((int));

static void interrupt(sig)
int sig;
{
	tcsetattr(0, TCSANOW, &saved_ttymode);
	err(1, "interrupted by signal %s", sys_siglist[sig]);
}

char *
readpass(buf,n)
char *buf;
int n;
{
	struct termios noecho_ttymode;
	void (*oldsig) __P((int));

	/* Save normal line editing modes */
	tcgetattr(0, &saved_ttymode);
	if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN)
		signal(SIGINT, interrupt);

	/* Turn off echoing */
	tcgetattr(0, &noecho_ttymode);
	noecho_ttymode.c_lflag &= ~ECHO;
	tcsetattr(0, TCSANOW, &noecho_ttymode);
	fgets(buf,n,stdin);
	rip(buf);

	/* Restore previous tty modes */
	tcsetattr(0, TCSANOW, &saved_ttymode);
	if (oldsig != SIG_IGN)
		signal(SIGINT, oldsig);

	/*
	after the secret key is taken from the keyboard, the line feed is
	written to standard error instead of standard output.  That means that
	anyone using the program from a terminal won't notice, but capturing
	standard output will get the key words without a newline in front of
	them.
	*/
        fprintf(stderr, "\n");
        fflush(stderr);
	sevenbit(buf);

	return buf;
}

void
sevenbit(s)
char *s;
{
	/* make sure there are only 7 bit code in the line*/
	while(*s){
		*s &= 0x7f;
		s++;
	}
}
OpenPOWER on IntegriCloud