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