Home | History | Annotate | Line # | Download | only in tspi
      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
     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
     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
    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