1
2/*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2004, 2005
8 *
9 */
10
11
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15#include <time.h>
16#include <errno.h>
17#include <unistd.h>
18#include <sys/types.h>
19#include <sys/mman.h>
20
21#include "trousers/tss.h"
22#include "trousers/trousers.h"
23#include "trousers_types.h"
24#include "spi_utils.h"
25#include "capabilities.h"
26#include "tsplog.h"
27#include "obj.h"
28
29#define	PGSIZE sysconf(_SC_PAGESIZE)
30#define PGOFFSET (PGSIZE - 1)
31#define PGMASK (~PGOFFSET)
32
33/*
34 *  popup_GetSecret()
35 *
36 *    newPIN - non-zero to popup the dialog to enter a new PIN, zero to popup a dialog
37 *      to enter an existing PIN
38 *    hash_mode - flag indicating whether to include null terminating data in the hash
39 *      of the secret (1.2 backport only).
40 *    popup_str - string to appear in the title bar of the popup dialog
41 *    auth_hash - the 20+ byte buffer that receives the SHA1 hash of the auth data
42 *      entered into the dialog box
43 *
44 */
45TSS_RESULT
46popup_GetSecret(UINT32 new_pin, UINT32 hash_mode, BYTE *popup_str, void *auth_hash)
47{
48	BYTE secret[UI_MAX_SECRET_STRING_LENGTH] = { 0 };
49	BYTE *dflt = (BYTE *)"TSS Authentication Dialog";
50	UINT32 secret_len = 0;
51	TSS_RESULT result;
52
53	if (popup_str == NULL)
54		popup_str = dflt;
55
56	/* pin the area where the secret will be put in memory */
57	if (pin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH)) {
58		LogError("Failed to pin secret in memory.");
59		return TSPERR(TSS_E_INTERNAL_ERROR);
60	}
61
62	if (new_pin)
63		DisplayNewPINWindow(secret, &secret_len, popup_str);
64	else
65		DisplayPINWindow(secret, &secret_len, popup_str);
66
67	if (!secret_len) {
68		unpin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH);
69		return TSPERR(TSS_E_POLICY_NO_SECRET);
70	}
71
72	if (hash_mode == TSS_TSPATTRIB_HASH_MODE_NOT_NULL)
73		secret_len -= sizeof(TSS_UNICODE); // Take off the NULL terminator
74
75	LogDebug("Hashing these %u bytes as the secret:", secret_len);
76	LogDebugData(secret_len, secret);
77	result = Trspi_Hash(TSS_HASH_SHA1, secret_len, secret, auth_hash);
78
79	/* zero, then unpin the memory */
80	__tspi_memset(secret, 0, secret_len);
81	unpin_mem(&secret, UI_MAX_SECRET_STRING_LENGTH);
82
83	return result;
84}
85
86int
87pin_mem(void *addr, size_t len)
88{
89	/* only root can lock pages into RAM */
90	if (getuid() != (uid_t)0) {
91		LogWarn("Not pinning secrets in memory due to insufficient perms.");
92		return 0;
93	}
94
95	len += (uintptr_t)addr & PGOFFSET;
96	addr = (void *)((uintptr_t)addr & PGMASK);
97	if (mlock(addr, len) == -1) {
98		LogError("mlock: %s", strerror(errno));
99		return 1;
100	}
101
102	return 0;
103}
104
105int
106unpin_mem(void *addr, size_t len)
107{
108	/* only root can lock pages into RAM */
109	if (getuid() != (uid_t)0) {
110		return 0;
111	}
112
113	len += (uintptr_t)addr & PGOFFSET;
114	addr = (void *)((uintptr_t)addr & PGMASK);
115	if (munlock(addr, len) == -1) {
116		LogError("mlock: %s", strerror(errno));
117		return 1;
118	}
119
120	return 0;
121}
122
123
124