Beispiel #1
0
Datei: memory.c Projekt: gpg/gsti
void *
_gsti_xrealloc (void *p, size_t n)
{
  void *pp = gcry_realloc (p, n);
  if (!pp)
    out_of_core ();
  return pp;
}
Beispiel #2
0
char * getPassphraseNcurses() {
    size_t size = PASSPHRASE_SIZE_INCS;
    char *ph = attemptSecureAlloc(size), *tmp;
    int written = 0, x, y;
    int ch;

    initscr();
    raw(); // Turn off buffering
    noecho(); // Turn off echoing
    keypad(stdscr, TRUE);
    clear();

    mvprintw(0, 0, "Enter decryption key: ");
    move(1, 0);
    curs_set(2);
    refresh();
    while (ch = getch()) {
        if (written >= PASSPHRASE_SIZE_INCS) {
            tmp = gcry_realloc(ph, size + PASSPHRASE_SIZE_INCS);
            if (tmp != NULL) {
                ph = tmp; written = 0;
            }
            else {
                getyx(stdscr, y, x);
                mvprintw(y + 1, 0, "Not enough memory for a longer passphrase.");
                move(y, x);
                refresh();
            }
        }

        if ((ch == KEY_BACKSPACE) || (ch == KEY_DC)) {
            if (written > 0) {
                --written;
                getyx(stdscr, y, x);
                move(y, x - 1);
                delch();
                refresh();
            }
            continue;
        }

        if (ch == '\n') {
            ph[written++] = '\0';
            break;
        }
        else {
            ph[written++] = ch;
            addch('*' | A_BOLD); refresh();
        }
    }
    clear();
    endwin();

    return ph;
}
Beispiel #3
0
void *
gcry_xrealloc( void *a, size_t n )
{
    void *p;

    while ( !(p = gcry_realloc( a, n )) ) {
	if( !outofcore_handler
	    || !outofcore_handler( outofcore_handler_value, n, 
                                   gcry_is_secure(a)? 3:2 ) ) {
	    _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
	}
    }
    return p;
}
Beispiel #4
0
extern void io_encryption_checksum(IO_HANDLE ptr, uint8_t **b, size_t *l)
{
	io_private_t *io_ptr = ptr;
	if (!io_ptr || io_ptr->fd < 0)
		return errno = EBADF , (void)NULL;
	if (!io_ptr->hash_init)
		return *l = 0 , (void)NULL;
	*l = gcry_md_get_algo_dlen(gcry_md_get_algo(io_ptr->hash_handle));
	uint8_t *x = gcry_realloc(*b, *l);
	if (!x)
		die(_("Out of memory @ %s:%d:%s [%zu]"), __FILE__, __LINE__, __func__, *l);
	*b = x;
	memcpy(*b, gcry_md_read(io_ptr->hash_handle, gcry_md_get_algo(io_ptr->hash_handle)), *l);
	return;
}
Beispiel #5
0
static gpg_err_code_t
make_space ( struct make_space_ctx *c, size_t n )
{
  size_t used = c->pos - c->sexp->d;

  if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
    {
      gcry_sexp_t newsexp;
      byte *newhead;
      size_t newsize;

      newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
      if (newsize <= c->allocated)
        return GPG_ERR_TOO_LARGE;
      newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
      if (!newsexp)
        return gpg_err_code_from_errno (errno);
      c->allocated = newsize;
      newhead = newsexp->d;
      c->pos = newhead + used;
      c->sexp = newsexp;
    }
  return 0;
}
Beispiel #6
0
static void
slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
{
    static int is_initialized = 0;
    static NETSTATISTICSGET pNetStatisticsGet = NULL;
    static NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
    static NETAPIBUFFERFREE pNetApiBufferFree = NULL;
    static int is_workstation = 1;

    static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
    PERF_DATA_BLOCK *pPerfData;
    HANDLE hDevice, hNetAPI32 = NULL;
    DWORD dwSize, status;
    int nDrive;

    if ( !is_initialized ) {
	HKEY hKey;

	if ( debug_me )
	    log_debug ("rndw32#slow_gatherer_nt: init toolkit\n" );
	/* Find out whether this is an NT server or workstation if necessary */
	if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
			  "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
			  0, KEY_READ, &hKey) == ERROR_SUCCESS) {
	    BYTE szValue[32];
	    dwSize = sizeof (szValue);

	    if ( debug_me )
		log_debug ("rndw32#slow_gatherer_nt: check product options\n" );
	    status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
				      szValue, &dwSize);
	    if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) {
		/* Note: There are (at least) three cases for ProductType:
		 * WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
		 * NT Server acting as a Domain Controller */
		is_workstation = 0;
		if ( debug_me )
		    log_debug ("rndw32: this is a NT server\n");
	    }
	    RegCloseKey (hKey);
	}

	/* Initialize the NetAPI32 function pointers if necessary */
	if ( (hNetAPI32 = LoadLibrary ("NETAPI32.DLL")) ) {
	    if ( debug_me )
		log_debug ("rndw32#slow_gatherer_nt: netapi32 loaded\n" );
	    pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
						       "NetStatisticsGet");
	    pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
						       "NetApiBufferSize");
	    pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
						       "NetApiBufferFree");

	    if ( !pNetStatisticsGet
		 || !pNetApiBufferSize || !pNetApiBufferFree ) {
		FreeLibrary (hNetAPI32);
		hNetAPI32 = NULL;
		log_debug ("rndw32: No NETAPI found\n" );
	    }
	}

	is_initialized = 1;
    }

    /* Get network statistics.	Note: Both NT Workstation and NT Server by
     * default will be running both the workstation and server services.  The
     * heuristic below is probably useful though on the assumption that the
     * majority of the network traffic will be via the appropriate service.
     * In any case the network statistics return almost no randomness */
    {	LPBYTE lpBuffer;
	if (hNetAPI32 && !pNetStatisticsGet (NULL,
			   is_workstation ? L"LanmanWorkstation" :
			   L"LanmanServer", 0, 0, &lpBuffer) ) {
	    if ( debug_me )
		log_debug ("rndw32#slow_gatherer_nt: get netstats\n" );
	    pNetApiBufferSize (lpBuffer, &dwSize);
	    (*add) ( lpBuffer, dwSize,requester );
	    pNetApiBufferFree (lpBuffer);
	}
    }

    /* Get disk I/O statistics for all the hard drives */
    for (nDrive = 0;; nDrive++) {
        char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT];
	char szDevice[50];

	/* Check whether we can access this device */
	sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
	hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
			      NULL, OPEN_EXISTING, 0, NULL);
	if (hDevice == INVALID_HANDLE_VALUE)
	    break;

	/* Note: This only works if you have turned on the disk performance
	 * counters with 'diskperf -y'.  These counters are off by default */
	if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
			     diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
			     &dwSize, NULL))
	{
	    if ( debug_me )
		log_debug ("rndw32#slow_gatherer_nt: iostats drive %d\n",
								  nDrive );
	    (*add) (diskPerformance, dwSize, requester );
	}
	else {
	    log_info ("NOTE: you should run 'diskperf -y' "
		      "to enable the disk statistics\n");
	}
	CloseHandle (hDevice);
    }

#if 0 /* we don't need this in GnuPG  */
    /* Wait for any async keyset driver binding to complete.  You may be
     * wondering what this call is doing here... the reason it's necessary is
     * because RegQueryValueEx() will hang indefinitely if the async driver
     * bind is in progress.  The problem occurs in the dynamic loading and
     * linking of driver DLL's, which work as follows:
     *
     * hDriver = LoadLibrary( DRIVERNAME );
     * pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 );
     * pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 );
     *
     * If RegQueryValueEx() is called while the GetProcAddress()'s are in
     * progress, it will hang indefinitely.  This is probably due to some
     * synchronisation problem in the NT kernel where the GetProcAddress()
     * calls affect something like a module reference count or function
     * reference count while RegQueryValueEx() is trying to take a snapshot
     * of the statistics, which include the reference counts.  Because of
     * this, we have to wait until any async driver bind has completed
     * before we can call RegQueryValueEx() */
    waitSemaphore (SEMAPHORE_DRIVERBIND);
#endif

    /* Get information from the system performance counters.  This can take
     * a few seconds to do.  In some environments the call to
     * RegQueryValueEx() can produce an access violation at some random time
     * in the future, adding a short delay after the following code block
     * makes the problem go away.  This problem is extremely difficult to
     * reproduce, I haven't been able to get it to occur despite running it
     * on a number of machines.  The best explanation for the problem is that
     * on the machine where it did occur, it was caused by an external driver
     * or other program which adds its own values under the
     * HKEY_PERFORMANCE_DATA key.  The NT kernel calls the required external
     * modules to map in the data, if there's a synchronisation problem the
     * external module would write its data at an inappropriate moment,
     * causing the access violation.  A low-level memory checker indicated
     * that ExpandEnvironmentStrings() in KERNEL32.DLL, called an
     * interminable number of calls down inside RegQueryValueEx(), was
     * overwriting memory (it wrote twice the allocated size of a buffer to a
     * buffer allocated by the NT kernel).  This may be what's causing the
     * problem, but since it's in the kernel there isn't much which can be
     * done.
     *
     * In addition to these problems the code in RegQueryValueEx() which
     * estimates the amount of memory required to return the performance
     * counter information isn't very accurate, since it always returns a
     * worst-case estimate which is usually nowhere near the actual amount
     * required.  For example it may report that 128K of memory is required,
     * but only return 64K of data */
    {	pPerfData =  gcry_xmalloc (cbPerfData);
	for (;;) {
	    dwSize = cbPerfData;
	    if ( debug_me )
		log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
	    status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
				      NULL, (LPBYTE) pPerfData, &dwSize);
	    if (status == ERROR_SUCCESS) {
		if (!memcmp (pPerfData->Signature, L"PERF", 8)) {
		    (*add) ( pPerfData, dwSize, requester );
		}
		else
		    log_debug ( "rndw32: no PERF signature\n");
		break;
	    }
	    else if (status == ERROR_MORE_DATA) {
		cbPerfData += PERFORMANCE_BUFFER_STEP;
		pPerfData = gcry_realloc (pPerfData, cbPerfData);
	    }
	    else {
		log_debug ( "rndw32: get performance data problem\n");
		break;
	    }
	}
	gcry_free (pPerfData);
    }
    /* Although this isn't documented in the Win32 API docs, it's necessary
       to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
       implicitly opened on the first call to RegQueryValueEx()).  If this
       isn't done then any system components which provide performance data
       can't be removed or changed while the handle remains active */
    RegCloseKey (HKEY_PERFORMANCE_DATA);
}
Beispiel #7
0
int main (int argc, char **argv) {
	/*
		Parse arguments
	*/
	if(opt_parse("usage: %s < filename > [options]", options, argv) == 0) {
		opt_help(0, NULL);
	}
		
	/*
		Read in password
	*/
	char *pass = NULL;
	size_t passLen = 0;
	ssize_t passRead;
	
	char *fileName;
		
	printf("Password: "******"libgcrypt version mismatch\n", stderr);
		exit (2);
	}

	gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN);
	gcry_control(GCRYCTL_INIT_SECMEM, 131072, 0);
	gcry_control(GCRYCTL_RESUME_SECMEM_WARN);
	gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);

	/*
		Key Generation
	*/
	char key[16] = "";
	size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);

	const char *salt = "NaCl";
	size_t saltLen = sizeof(salt);
	unsigned long iterations = 4096;
	gpg_error_t errStatus;
		
	errStatus = gcry_kdf_derive(pass, passLen, GCRY_KDF_PBKDF2, GCRY_MD_SHA512, salt, saltLen, iterations, keyLength, key);
			
	/*
		Cipher Setup
	*/
//	printf("Key: %X\n", key);
	puts(key);
	
	const char* IV = "5844"; // const int IV = 5844;
	const char *name = "aes128";
	int algorithm = gcry_cipher_map_name(name);
	size_t blockLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
	gcry_cipher_hd_t hand;

	gcry_cipher_open(&hand, algorithm, GCRY_CIPHER_MODE_CBC, 0);
	gcry_cipher_setkey(hand, key, keyLength);
	gcry_cipher_setiv(hand, IV, blockLength);
	
	char *buffer;
	long len;
	size_t macLen = 0;
	
	/*
		If the local flag is set then we encrypt the file locally
		instead of sending it over the network
		Otherwise we send the file over the network
	*/
	if (local == 1) {
	
		/* 
			Open the file for reading and then copy to a buffer
		*/	
		FILE *ifp = fopen(argv[1], "rb");
		if(ifp == 0) {
			printf("%s", "Could not open file");
			return 1;
		}
		
		// Lets figure out how big the file is
		fseek(ifp, 0L, SEEK_END);
		len = ftell(ifp);
		rewind(ifp);
		
		// Allocate secure RAM for the buffer
		buffer = gcry_calloc_secure(len, sizeof(char));

		// Copy the input file to the buffer
		fread(buffer, 1, len, ifp);
		
		// Since we're running locally, the name of the output file is the same as the argument
		// without the .gt
		fileName = argv[1];
		size_t inLen = strlen(fileName);

		// End the filename by replacing the "." with a NULL char
		fileName[inLen-3] = '\0';
	
		fclose(ifp);
		
	} else {
		/*
			Retrieve file from remote computer
			Open a socket and listen for communication
		*/
		int sock;
		int localSock;
		struct sockaddr_in inPort;
		
		inPort.sin_family = AF_INET;
		inPort.sin_addr.s_addr = INADDR_ANY;
		inPort.sin_port = htons(port);
	
		sock = socket(AF_INET, SOCK_STREAM, 0);

		if (sock == -1) {
			printf("%s", "Could not open socket");
			exit(1);
		}
		
		bind(sock, (struct sockaddr *) &inPort, sizeof(inPort));
		listen(sock, 0);
		
		printf("%s", "Waiting for connection...\n");
		
		// Accepting the connection
		localSock = accept(sock, NULL, NULL);
		printf("%s", "Inbound file...\n");
		
		// Allocate some memory for the buffer
		// len+(160(len%16)) is so that the memory we allocate is divisible 
		// by the blocklength, which is 16
        len = 4096L;
		buffer = gcry_calloc_secure(len+(16-(len%16)), sizeof(char));
        long dataRead = 0L;
        int keepReading = 1;
		
		// Let's figure out how much data we're getting
		// If I were to do this part over, I would instead open two connections
		// from techrypt- where the first connection sends the 
		// amount of data to be transmitted in the second connection
        while (keepReading) {
            dataRead = recv(localSock, buffer, len, MSG_PEEK);
            if (dataRead == len) {
                len = len * 2;
				sleep(.5);
                buffer = gcry_realloc(buffer, len);
                keepReading = 1;
            } else {
                keepReading = 0;
            }
        }
		// How much data did we read?
        len = dataRead;
		
		// Now lets actually store it in the buffer
        dataRead = recv(localSock, buffer, len, 0);
		
		// Output file name is the command line argument
		fileName = argv[1];
			
		close(sock);
		
		/*
			Setup the HMAC
		*/
		gcry_md_hd_t macHand;
	
		macLen = gcry_md_get_algo_dlen(GCRY_MD_SHA512);
		char *mac = gcry_calloc_secure(macLen, sizeof(char));
		
		gcry_md_open(&macHand, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
		gcry_md_setkey(macHand, key, keyLength);
		
		// Generate the HMAC for the message we received
		// Since we know there's a MAC of size macLen at the end
		// we will only generate the hash based on the first
		// len-macLen bytes
		gcry_md_write(macHand, buffer, len-macLen);
		mac = gcry_md_read(macHand, 0);
		
		/*
			Strip HMAC from buffer
		*/
		char *exMac = buffer+(len-macLen);
		
		/*
			Check HMAC against our HMAC
		*/
		// I think this may be exploitable with a strategically placed NULL
		// The use of memcmp could fix this...if I have time I will replace and check
		if(strncmp(mac, exMac, macLen) != 0) {
			exit(62);
		}
								
	}	
	

	/*
		Decrypt the buffer
	*/
	gcry_cipher_decrypt(hand, buffer, len, NULL, 0);
	
	
	/*
		Reverse padding algorithm
		Strip the amount of bytes from the end of the file
		determined by the contents of the last byte
		This is why using PKCS7 was so useful
	*/
	char *padPtr = buffer+len-macLen-1;
	int writeLen = len-macLen-(*padPtr);
	
	/*
		Write the buffer to a file
	*/
	FILE *ofp = fopen(fileName, "wb");
	fwrite(buffer, 1, writeLen, ofp);
	
	fclose(ofp);
		
	return 0;
}