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  */
45 TSS_RESULT
popup_GetSecret(UINT32 new_pin,UINT32 hash_mode,BYTE * popup_str,void * auth_hash)46 popup_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 
86 int
pin_mem(void * addr,size_t len)87 pin_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 
105 int
unpin_mem(void * addr,size_t len)106 unpin_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