├── .gitignore ├── README.md ├── intro_enclave-app_msg_passing ├── ConsoleApplication1.cpp ├── Enclave1.cpp └── README └── passwordManager ├── README ├── keypass part1+2.docx ├── passwordManagerApp ├── passwordManagerApp.sln └── passwordManagerApp │ ├── Crypto.cpp │ ├── Crypto.h │ ├── DRNG.cpp │ ├── DRNG.h │ ├── ReadMe.txt │ ├── SGXWrapper.cpp │ ├── SGXWrapper.h │ ├── passwordManagerApp.cpp │ ├── passwordManagerApp.vcxproj │ ├── passwordManagerApp.vcxproj.filters │ ├── passwordManagerEnclave.signed.dll │ ├── stdafx.cpp │ ├── stdafx.h │ ├── targetver.h │ └── tests │ └── CryptoTests │ ├── CryptoTests.cpp │ ├── CryptoTests.sln │ ├── CryptoTests.vcxproj │ ├── CryptoTests.vcxproj.filters │ ├── ReadMe.txt │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h └── passwordManagerEnclave ├── passwordManagerEnclave.sln └── passwordManagerEnclave ├── E_Crypto.cpp ├── E_Crypto.h ├── E_DRNG.cpp ├── E_DRNG.h ├── ReadMe.txt ├── passwordManagerEnclave.config.xml ├── passwordManagerEnclave.cpp ├── passwordManagerEnclave.edl ├── passwordManagerEnclave.h ├── passwordManagerEnclave.vcxproj ├── passwordManagerEnclave.vcxproj.filters └── passwordManagerEnclave_private.pem /.gitignore: -------------------------------------------------------------------------------- 1 | Release/ 2 | Debug/ 3 | ipch/ 4 | x64/ 5 | *.sdf 6 | *.opensdf 7 | *.vcxproj.user 8 | *.suo 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SGX 2 | Code samples and tutorials for using intel software guard extensions 3 | -------------------------------------------------------------------------------- /intro_enclave-app_msg_passing/ConsoleApplication1.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "stdafx.h" 3 | #include "sgx_urts.h" 4 | #include "Enclave1_u.h" 5 | #include 6 | #include "sgx_capable.h" 7 | #include "sgx_uae_service.h" 8 | 9 | #define ENCLAVE_FILE _T("Enclave1.signed.dll") 10 | #define MAX_BUF_LEN 100 11 | 12 | 13 | int main() 14 | { 15 | 16 | sgx_enclave_id_t enclaveId = NULL; 17 | sgx_status_t ret = SGX_SUCCESS; 18 | sgx_launch_token_t token = {0}; 19 | sgx_launch_token_t *launchToken = NULL; 20 | int updated, i=0; 21 | char buffer[MAX_BUF_LEN] = "Initial string, before enclave calls"; 22 | 23 | if(sgx_is_capable(&updated) != SGX_ENABLED) 24 | { 25 | printf("Error %#x: SGX is not enabled on this device\n", ret); 26 | return -1; 27 | } 28 | 29 | printf("%i: %s\n", i++, buffer); 30 | 31 | ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, 32 | &enclaveId, NULL); 33 | if(ret != SGX_SUCCESS) 34 | { 35 | printf("Error %#x: cannot create enclave\n", ret); 36 | return -1; 37 | } 38 | 39 | enclaveOutFunction(enclaveId, buffer, MAX_BUF_LEN); 40 | printf("%i: %s\n", i++, buffer); 41 | 42 | //set the internal enclave function 43 | strcpy_s(buffer,"Changed the enclave string"); 44 | enclaveInFunction(enclaveId, buffer, MAX_BUF_LEN); 45 | 46 | //swap values with enclave string 47 | strcpy_s(buffer,"New value application string"); 48 | enclaveInOutFunction(enclaveId, buffer, MAX_BUF_LEN); 49 | 50 | //now, buffer should be "Changed the enclave string" 51 | printf("%i: %s\n", i++, buffer); 52 | 53 | //swap again; next output should be "New value for application string" 54 | enclaveInOutFunction(enclaveId, buffer, MAX_BUF_LEN); 55 | printf("%i: %s\n", i++, buffer); 56 | 57 | //grab the pre-swapped string "Changed the enclave string" 58 | enclaveOutFunction(enclaveId, buffer, MAX_BUF_LEN); 59 | printf("%i: %s\n", i++, buffer); 60 | 61 | 62 | if(sgx_destroy_enclave(enclaveId) != SGX_SUCCESS) 63 | { 64 | printf("Error %x: cant destroy enclave\n", ret); 65 | return -1; 66 | } 67 | else printf("DONE\n"); 68 | getchar(); 69 | 70 | /* 71 | Final output should be: 72 | 0: Initial string, before enclave calls 73 | 1: Internal enclave string is not initialized 74 | 2: Changed the enclave string 75 | 3: New value application string 76 | 4: Changed the enclave string 77 | DONE 78 | */ 79 | return 0; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /intro_enclave-app_msg_passing/Enclave1.cpp: -------------------------------------------------------------------------------- 1 | #include "Enclave1_t.h" 2 | #include "sgx_trts.h" 3 | #include 4 | #include 5 | 6 | #define MAX_BUF_LEN 100 7 | char enclaveString[MAX_BUF_LEN] = "Internal enclave string is not initialized"; 8 | 9 | /* 10 | Decsription: This function demonstrates the use of an 'out' enclave by 11 | changing the value of an externally provided input parameter. Data 12 | is sent from the enclave to the application 13 | */ 14 | void enclaveOutFunction(char *buf, size_t len) 15 | { 16 | if(len < MAX_BUF_LEN) 17 | buf = (char*)malloc(MAX_BUF_LEN); 18 | 19 | memcpy(buf,enclaveString,strlen(enclaveString)+1); 20 | /* 21 | const char *secret = "Hello Enclave!"; 22 | if(len > strlen(secret)) 23 | { 24 | memcpy(buf,secret,strlen(secret)+1); 25 | } 26 | */ 27 | } 28 | 29 | /* 30 | Decsription: This function demonstrates the use of an 'in' enclave by 31 | using external/non-enclave variable to set an internal/enclave value. 32 | Data is sent from the application into the enclave. 33 | */ 34 | void enclaveInFunction(char *buf, size_t len) 35 | { 36 | if(len <= (size_t)MAX_BUF_LEN) 37 | memcpy(enclaveString,buf,strlen(buf)+1); 38 | } 39 | 40 | /* 41 | Decsription: This function demonstrates the use of both an 'in' and 'out' 42 | enclave by swapping the values of the input string and the internal 43 | enclave string. Data is exchanged between the application and enclave. 44 | */ 45 | void enclaveInOutFunction(char *buf, size_t len) 46 | { 47 | //if(strlen(buf) <= MAX_BUF_LEN) 48 | { 49 | char *tmp = (char*)malloc(MAX_BUF_LEN*sizeof(char)); 50 | memcpy(tmp,buf,strlen(buf)+1); 51 | memcpy(buf,enclaveString,strlen(enclaveString)+1); 52 | memcpy(enclaveString,tmp,strlen(tmp)+1); 53 | free(tmp); 54 | } 55 | } -------------------------------------------------------------------------------- /intro_enclave-app_msg_passing/README: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /passwordManager/README: -------------------------------------------------------------------------------- 1 | passwordManagerEnclave contains enclave code that will be officially used for the GUI/app 2 | 3 | passwordManagerApp contains code to demo and test enclave code 4 | -------------------------------------------------------------------------------- /passwordManager/keypass part1+2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelSoftware/Tutorial-Password-Manager-with-Intel-SGX/0071bccef06791ddbffb61d6827f0957c143c578/passwordManager/keypass part1+2.docx -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "passwordManagerApp", "passwordManagerApp\passwordManagerApp.vcxproj", "{BA553623-C2EE-4FD0-9FE0-17CEF25B5B45}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {BA553623-C2EE-4FD0-9FE0-17CEF25B5B45}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {BA553623-C2EE-4FD0-9FE0-17CEF25B5B45}.Debug|Win32.Build.0 = Debug|Win32 14 | {BA553623-C2EE-4FD0-9FE0-17CEF25B5B45}.Release|Win32.ActiveCfg = Release|Win32 15 | {BA553623-C2EE-4FD0-9FE0-17CEF25B5B45}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/Crypto.cpp: -------------------------------------------------------------------------------- 1 | #include "Crypto.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | Crypto::Crypto(void) 8 | { 9 | } 10 | 11 | 12 | Crypto::~Crypto(void) 13 | { 14 | } 15 | 16 | crypto_status_t Crypto::generate_database_key (BYTE key_out[16], GenerateDatabaseKeyCallback callback) 17 | { 18 | ULONG count= 0; 19 | 20 | while ( (count= drng.get_seed_bytes(&key_out[count], 16)) < 16 ) { 21 | if ( callback != NULL ) { 22 | int rv; 23 | // So that the GUI can show a progress indicator, a cancel button, etc. 24 | rv= callback(count, 16); 25 | if ( rv == 0 ) { 26 | // A zero return value from the callback means we should abort. 27 | return CRYPTO_ERR_USER_CANCEL; 28 | } 29 | } 30 | } 31 | 32 | if ( callback != NULL ) callback(16, 16); 33 | return CRYPTO_OK; 34 | } 35 | 36 | crypto_status_t Crypto::derive_master_key (PBYTE passphrase, DWORD passphrase_len, BYTE salt[8], BYTE key_out[16]) 37 | { 38 | return this->derive_master_key_ex(passphrase, passphrase_len, (PBYTE) salt, 8, CRYPTO_KDF_ITERATIONS, key_out); 39 | } 40 | 41 | crypto_status_t Crypto::derive_master_key_ex (PBYTE passphrase, DWORD passphrase_len, PBYTE salt, DWORD salt_len, ULONG iterations, BYTE key_out[16]) 42 | { 43 | PBYTE messages[3]= { passphrase, salt, NULL }; 44 | DWORD lengths[3]= { passphrase_len, salt_len, 0 }; 45 | BYTE msg[32], md[32], key[32]; 46 | ULONG i; 47 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 48 | 49 | rv= this->sha256_multi(messages, lengths, md); 50 | if ( rv != CRYPTO_OK ) { 51 | return rv; 52 | } 53 | memcpy(key, md, 32); 54 | 55 | messages[1]= msg; 56 | lengths[1]= 32; 57 | 58 | for (i= 0; i< iterations; ++i) { 59 | int j; 60 | 61 | memcpy(msg, md, 32); 62 | rv= this->sha256_multi(messages, lengths, md); 63 | if ( rv != CRYPTO_OK) { 64 | return rv; 65 | } 66 | 67 | // The compiler will optimize this 68 | for (j= 0; j<32; ++j) key[j]^= md[j]; 69 | } 70 | 71 | memcpy(key_out, &(key[8]), 16); 72 | 73 | return CRYPTO_OK; 74 | } 75 | 76 | crypto_status_t Crypto::validate_passphrase (PBYTE passphrase, ULONG passphrase_len, BYTE salt[8], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]) 77 | { 78 | return this->validate_passphrase_ex(passphrase, passphrase_len, (PBYTE) salt, CRYPTO_KDF_SALT_LEN, CRYPTO_KDF_ITERATIONS, db_key_ct, iv, tag, db_key_pt); 79 | } 80 | 81 | crypto_status_t Crypto::validate_passphrase_ex (PBYTE passphrase, ULONG passphrase_len, PBYTE salt, ULONG salt_len, ULONG iterations, BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]) 82 | { 83 | BYTE mkey[16]; 84 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 85 | 86 | rv= this->derive_master_key_ex(passphrase, passphrase_len, salt, salt_len, iterations, mkey); 87 | if ( rv != CRYPTO_OK ) { 88 | return rv; 89 | } 90 | 91 | rv= this->decrypt_database_key(mkey, db_key_ct, iv, tag, db_key_pt); 92 | if (rv == CRYPTO_ERR_DECRYPT_AUTH) return CRYPTO_ERR_PASS_MISMATCH; 93 | 94 | return rv; 95 | } 96 | 97 | crypto_status_t Crypto::generate_salt (BYTE salt[8]) 98 | { 99 | return this->generate_salt_ex(salt, CRYPTO_KDF_SALT_LEN); 100 | } 101 | 102 | crypto_status_t Crypto::generate_salt_ex (BYTE *salt, ULONG salt_len) 103 | { 104 | ULONG n= drng.get_rand_bytes(salt, salt_len); 105 | if ( n != salt_len ) { 106 | // RDRAND should not fail unless something bad has happened. 107 | return CRYPTO_ERR_DRNG; 108 | } 109 | 110 | return CRYPTO_OK; 111 | } 112 | 113 | crypto_status_t Crypto::generate_nonce_gcm (BYTE *nonce) 114 | { 115 | ULONG n= drng.get_rand_bytes(nonce, 12); 116 | if ( n != 12 ) { 117 | // RDRAND should not fail unless something bad has happened. 118 | return CRYPTO_ERR_DRNG; 119 | } 120 | 121 | return CRYPTO_OK; 122 | } 123 | 124 | crypto_status_t Crypto::encrypt_database_key (BYTE master_key[16], BYTE db_key_pt[16], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], DWORD flags) 125 | { 126 | crypto_status_t rv; 127 | 128 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 129 | rv= this->generate_nonce_gcm(iv); 130 | if ( rv != CRYPTO_OK ) { 131 | return rv; 132 | } 133 | } 134 | 135 | return this->aes_128_gcm_encrypt(master_key, iv, 12, db_key_pt, 16, db_key_ct, 16, tag, 16); 136 | } 137 | 138 | crypto_status_t Crypto::decrypt_database_key (BYTE master_key[16], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]) 139 | { 140 | return this->aes_128_gcm_decrypt(master_key, iv, 12, db_key_ct, 16, db_key_pt, 16, tag, 16); 141 | } 142 | 143 | crypto_status_t Crypto::encrypt_account_password (BYTE db_key[16], PBYTE password_pt, ULONG password_len, PBYTE password_ct, BYTE iv[12], BYTE tag[16], DWORD flags) 144 | { 145 | crypto_status_t rv; 146 | 147 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 148 | rv= this->generate_nonce_gcm(iv); 149 | if ( rv != CRYPTO_OK ) { 150 | return rv; 151 | } 152 | } 153 | 154 | return this->aes_128_gcm_encrypt(db_key, iv, 12, password_pt, password_len, password_ct, password_len, tag, 16); 155 | } 156 | 157 | crypto_status_t Crypto::decrypt_account_password (BYTE db_key[16], PBYTE password_ct, ULONG password_len, BYTE iv[12], BYTE tag[16], PBYTE password) 158 | { 159 | return this->aes_128_gcm_decrypt(db_key, iv, 12, password_ct, password_len, password, password_len, tag, 16); 160 | } 161 | 162 | crypto_status_t Crypto::encrypt_database (BYTE db_key[16], PBYTE db_serialized, ULONG db_size, PBYTE db_ct, BYTE iv[12], BYTE tag[16], DWORD flags) 163 | { 164 | crypto_status_t rv; 165 | 166 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 167 | rv= this->generate_nonce_gcm(iv); 168 | if ( rv != CRYPTO_OK ) { 169 | return rv; 170 | } 171 | } 172 | 173 | return this->aes_128_gcm_encrypt(db_key, iv, 12, db_serialized, db_size, db_ct, db_size, tag, 16); 174 | } 175 | 176 | crypto_status_t Crypto::decrypt_database (BYTE db_key[16], PBYTE db_ct, ULONG db_size, BYTE iv[12], BYTE tag[16], PBYTE db_serialized) 177 | { 178 | return this->aes_128_gcm_decrypt(db_key, iv, 12, db_ct, db_size, db_serialized, db_size, tag, 16); 179 | } 180 | 181 | crypto_status_t Crypto::aes_init (BCRYPT_ALG_HANDLE *halgo, LPCWSTR algo_id, PBYTE chaining_mode, 182 | DWORD chaining_mode_len, BCRYPT_KEY_HANDLE *hkey, PBYTE key, ULONG key_len) 183 | { 184 | NTSTATUS status; 185 | 186 | status= BCryptOpenAlgorithmProvider(halgo, algo_id, NULL, 0); 187 | if ( status != STATUS_SUCCESS ) { 188 | // Error 189 | return CRYPTO_ERR_OPEN_PROVIDER; 190 | } 191 | 192 | if ( chaining_mode != NULL ) { 193 | status= BCryptSetProperty(*halgo, BCRYPT_CHAINING_MODE, chaining_mode, chaining_mode_len, 0); 194 | if ( status != STATUS_SUCCESS ) { 195 | // Error 196 | BCryptCloseAlgorithmProvider(*halgo, 0); 197 | return CRYPTO_ERR_SET_PROP; 198 | } 199 | } 200 | 201 | status= BCryptGenerateSymmetricKey(*halgo, hkey, NULL, 0, key, key_len, 0); 202 | if ( status != STATUS_SUCCESS ) { 203 | // Error 204 | BCryptCloseAlgorithmProvider(*halgo, 0); 205 | return CRYPTO_ERR_SET_KEY; 206 | } 207 | 208 | return CRYPTO_OK; 209 | } 210 | 211 | void Crypto::aes_close (BCRYPT_ALG_HANDLE *halgo, BCRYPT_KEY_HANDLE *hkey) 212 | { 213 | if ( *halgo != NULL ) BCryptCloseAlgorithmProvider(*halgo, 0); 214 | if ( *hkey != NULL ) BCryptDestroyKey(*hkey); 215 | } 216 | 217 | // Assumes the counter is kept in the low 64 bits. 218 | 219 | crypto_status_t Crypto::aes_128_ctr_encrypt(PBYTE key, PBYTE nonce_in, ULONG nonce_len, PBYTE pt, DWORD pt_len, PBYTE ct) 220 | { 221 | BCRYPT_ALG_HANDLE halgo= NULL; 222 | BCRYPT_KEY_HANDLE hkey= NULL; 223 | ULONG blocks= pt_len/16 + ((pt_len%16) ? 1 : 0); 224 | ULONG rem= pt_len; 225 | ULONG i, j, len; 226 | PBYTE ppt= pt; 227 | PBYTE pct= ct; 228 | BYTE nonce[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; 229 | NTSTATUS status; 230 | ULONGLONG ctr= 0; 231 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 232 | 233 | rv= this->aes_init(&halgo, BCRYPT_AES_ALGORITHM, NULL, 0, &hkey, key, 16); 234 | if ( rv != CRYPTO_OK ) { 235 | return rv; 236 | } 237 | 238 | memcpy(nonce, nonce_in, nonce_len); 239 | 240 | for (i= 0; i= 16) ? 16 : rem; 242 | 243 | status= BCryptEncrypt(hkey, nonce, 16, NULL, NULL, 0, pct, 16, &len, 0); 244 | if ( status != STATUS_SUCCESS || len != 16 ) { 245 | rv= CRYPTO_ERR_ENCRYPT; 246 | goto cleanup; 247 | } 248 | 249 | for(j= 0; j< chunk; ++j) { 250 | pct[j]^= ppt[j]; 251 | } 252 | ppt+= chunk; 253 | pct+= chunk; 254 | ++ctr; 255 | 256 | memcpy(&ctr, &nonce[8], 8); 257 | ctr= _byteswap_uint64(ctr); 258 | ++ctr; 259 | ctr= _byteswap_uint64(ctr); 260 | memcpy(&nonce[8], &ctr, 8); 261 | } 262 | 263 | memcpy(nonce_in, nonce, 16); 264 | 265 | rv= CRYPTO_OK; 266 | 267 | cleanup: 268 | this->aes_close(&halgo, &hkey); 269 | 270 | return rv; 271 | } 272 | 273 | crypto_status_t Crypto::aes_128_gcm_encrypt(PBYTE key, PBYTE nonce, ULONG nonce_len, PBYTE pt, DWORD pt_len, PBYTE ct, DWORD ct_sz, PBYTE tag, DWORD tag_len) 274 | { 275 | BCRYPT_ALG_HANDLE halgo= NULL; 276 | BCRYPT_KEY_HANDLE hkey= NULL; 277 | BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authinfo; 278 | NTSTATUS status; 279 | DWORD ct_len; 280 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 281 | 282 | rv= this->aes_init(&halgo, BCRYPT_AES_ALGORITHM, (PBYTE) BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), &hkey, key, 16); 283 | if ( rv != CRYPTO_OK ) { 284 | return rv; 285 | } 286 | 287 | BCRYPT_INIT_AUTH_MODE_INFO(authinfo); 288 | authinfo.pbNonce= &nonce[0]; 289 | authinfo.cbNonce= nonce_len; 290 | authinfo.pbTag= &tag[0]; 291 | authinfo.cbTag= tag_len; 292 | 293 | status= BCryptEncrypt(hkey, pt, pt_len, (PBYTE) &authinfo, NULL, 0, ct, ct_sz, &ct_len, 0); 294 | if ( status != STATUS_SUCCESS ) { 295 | rv= CRYPTO_ERR_ENCRYPT; 296 | } else { 297 | rv= CRYPTO_OK; 298 | } 299 | 300 | cleanup: 301 | this->aes_close(&halgo, &hkey); 302 | 303 | return rv; 304 | } 305 | 306 | crypto_status_t Crypto::aes_128_gcm_decrypt(PBYTE key, PBYTE nonce, ULONG nonce_len, PBYTE ct, DWORD ct_len, PBYTE pt, DWORD pt_sz, PBYTE tag, DWORD tag_len) 307 | { 308 | BCRYPT_ALG_HANDLE halgo= NULL; 309 | BCRYPT_KEY_HANDLE hkey= NULL; 310 | BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authinfo; 311 | NTSTATUS status; 312 | DWORD pt_len; 313 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 314 | 315 | rv= this->aes_init(&halgo, BCRYPT_AES_ALGORITHM, (PBYTE) BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), &hkey, key, 16); 316 | if ( rv != CRYPTO_OK ) { 317 | return rv; 318 | } 319 | 320 | BCRYPT_INIT_AUTH_MODE_INFO(authinfo); 321 | authinfo.pbNonce= &nonce[0]; 322 | authinfo.cbNonce= nonce_len; 323 | authinfo.pbTag= &tag[0]; 324 | authinfo.cbTag= tag_len; 325 | 326 | status= BCryptDecrypt(hkey, ct, ct_len, (PBYTE) &authinfo, NULL, 0, pt, pt_sz, &pt_len, 0); 327 | if ( status != STATUS_SUCCESS ) { 328 | if ( status == STATUS_AUTH_TAG_MISMATCH ) rv= CRYPTO_ERR_DECRYPT_AUTH; 329 | else rv= CRYPTO_ERR_DECRYPT; 330 | } else { 331 | rv= CRYPTO_OK; 332 | } 333 | 334 | cleanup: 335 | this->aes_close(&halgo, &hkey); 336 | 337 | return rv; 338 | } 339 | 340 | crypto_status_t Crypto::sha256 (PBYTE message, ULONG message_length, BYTE md[32]) 341 | { 342 | PBYTE messages[2]= { message, NULL }; 343 | ULONG lengths[2]= { message_length, 0 }; 344 | 345 | return this->sha256_multi(messages, lengths, md); 346 | } 347 | 348 | crypto_status_t Crypto::sha256_multi (PBYTE *messages, ULONG *lengths, BYTE md[32]) 349 | { 350 | BCRYPT_ALG_HANDLE halgo= NULL; 351 | BCRYPT_HASH_HANDLE hhash= NULL; 352 | NTSTATUS status; 353 | DWORD hashobjlen= 310; //Size for SHA-256 354 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 355 | BYTE hashobject[310]; //Size for SHA-256 356 | PBYTE *message= messages; 357 | ULONG *length= lengths; 358 | DWORD result= 0; 359 | 360 | status= BCryptOpenAlgorithmProvider(&halgo, BCRYPT_SHA256_ALGORITHM, NULL, 0); 361 | if ( status != STATUS_SUCCESS ) { 362 | return CRYPTO_ERR_OPEN_PROVIDER; 363 | } 364 | 365 | status = BCryptCreateHash(halgo, &hhash, hashobject, hashobjlen, NULL, 0, 0); 366 | if ( status != STATUS_SUCCESS ) { 367 | BCryptCloseAlgorithmProvider(halgo, 0); 368 | return CRYPTO_ERR_CREATE_HASH; 369 | } 370 | 371 | while ( *message != NULL ) { 372 | status= BCryptHashData(hhash, *message, *length, 0); 373 | if ( status != STATUS_SUCCESS ) { 374 | rv= CRYPTO_ERR_HASH_DATA; 375 | goto cleanup; 376 | } 377 | ++message; 378 | ++length; 379 | } 380 | 381 | status= BCryptFinishHash(hhash, md, 32, 0); 382 | if ( status != STATUS_SUCCESS ) { 383 | rv= CRYPTO_ERR_FINISH_HASH; 384 | } else { 385 | rv= CRYPTO_OK; 386 | } 387 | 388 | cleanup: 389 | BCryptDestroyHash(hhash); 390 | BCryptCloseAlgorithmProvider(halgo, 0); 391 | 392 | return rv; 393 | } 394 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/Crypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "DRNG.h" 7 | 8 | #define CRYPTO_KDF_ITERATIONS 50000 9 | #define CRYPTO_KDF_SALT_LEN 8 10 | 11 | #define CRYPTO_OK 0x00000000 12 | #define CRYPTO_ERR_OPEN_PROVIDER 0x10000001 13 | #define CRYPTO_ERR_CREATE_HASH 0x10000002 14 | #define CRYPTO_ERR_HASH_DATA 0x10000003 15 | #define CRYPTO_ERR_FINISH_HASH 0x10000004 16 | #define CRYPTO_ERR_SET_PROP 0x10000005 17 | #define CRYPTO_ERR_GET_PROP 0x10000006 18 | #define CRYPTO_ERR_SET_KEY 0x10000007 19 | 20 | #define CRYPTO_ERR_DECRYPT 0x10000010 21 | #define CRYPTO_ERR_DECRYPT_AUTH 0x10000011 22 | #define CRYPTO_ERR_ENCRYPT 0x10000012 23 | 24 | #define CRYPTO_ERR_PASS_MISMATCH 0x10000100 25 | #define CRYPTO_ERR_USER_CANCEL 0x10000101 26 | 27 | #define CRYPTO_ERR_DRNG 0x20000001 28 | 29 | #define CRYPTO_ERR_UNKNOWN 0xF0000001 30 | 31 | #define CRYPTO_F_IV_PROVIDED 0x00000001 32 | 33 | typedef int (*GenerateDatabaseKeyCallback)(int, int); 34 | typedef ULONG crypto_status_t; 35 | 36 | class Crypto 37 | { 38 | DRNG drng; 39 | 40 | crypto_status_t aes_init (BCRYPT_ALG_HANDLE *halgo, LPCWSTR algo_id, PBYTE chaining_mode, DWORD chaining_mode_len, BCRYPT_KEY_HANDLE *hkey, PBYTE key, ULONG key_len); 41 | void aes_close (BCRYPT_ALG_HANDLE *halgo, BCRYPT_KEY_HANDLE *hkey); 42 | 43 | crypto_status_t aes_128_gcm_encrypt(PBYTE key, PBYTE nonce, ULONG nonce_len, PBYTE pt, DWORD pt_len, PBYTE ct, DWORD ct_sz, PBYTE tag, DWORD tag_len); 44 | crypto_status_t aes_128_gcm_decrypt(PBYTE key, PBYTE nonce, ULONG nonce_len, PBYTE ct, DWORD ct_len, PBYTE pt, DWORD pt_sz, PBYTE tag, DWORD tag_len); 45 | crypto_status_t aes_128_ctr_encrypt(PBYTE key, PBYTE nonce, ULONG nonce_len, PBYTE pt, DWORD pt_len, PBYTE ct); 46 | crypto_status_t sha256 (PBYTE message, DWORD message_len, BYTE hash[32]); 47 | crypto_status_t sha256_multi (PBYTE *messages, ULONG *lengths, BYTE hash[32]); 48 | 49 | public: 50 | Crypto(void); 51 | ~Crypto(void); 52 | 53 | crypto_status_t generate_database_key (BYTE key_out[16], GenerateDatabaseKeyCallback callback); 54 | crypto_status_t generate_salt (BYTE salt[8]); 55 | crypto_status_t generate_salt_ex (PBYTE salt, ULONG salt_len); 56 | crypto_status_t generate_nonce_gcm (BYTE nonce[12]); 57 | 58 | crypto_status_t derive_master_key (PBYTE passphrase, ULONG passphrase_len, BYTE salt[8], BYTE key_out[16]); 59 | crypto_status_t derive_master_key_ex (PBYTE passphrase, ULONG passphrase_len, PBYTE salt, ULONG salt_len, ULONG iterations, BYTE key_out[16]); 60 | 61 | crypto_status_t validate_passphrase (PBYTE passphrase, ULONG passphrase_len, BYTE salt[8], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]); 62 | crypto_status_t validate_passphrase_ex (PBYTE passphrase, ULONG passphrase_len, PBYTE salt, ULONG salt_len, ULONG iterations, BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]); 63 | 64 | crypto_status_t encrypt_database_key (BYTE master_key[16], BYTE db_key_pt[16], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], DWORD flags= 0); 65 | crypto_status_t decrypt_database_key (BYTE master_key[16], BYTE db_key_ct[16], BYTE iv[12], BYTE tag[16], BYTE db_key_pt[16]); 66 | 67 | crypto_status_t encrypt_account_password (BYTE db_key[16], PBYTE password_pt, ULONG password_len, PBYTE password_ct, BYTE iv[12], BYTE tag[16], DWORD flags= 0); 68 | crypto_status_t decrypt_account_password (BYTE db_key[16], PBYTE password_ct, ULONG password_len, BYTE iv[12], BYTE tag[16], PBYTE password); 69 | 70 | crypto_status_t encrypt_database (BYTE db_key[16], PBYTE db_serialized, ULONG db_size, PBYTE db_ct, BYTE iv[12], BYTE tag[16], DWORD flags= 0); 71 | crypto_status_t decrypt_database (BYTE db_key[16], PBYTE db_ct, ULONG db_size, BYTE iv[12], BYTE tag[16], PBYTE db_serialized); 72 | }; 73 | 74 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/DRNG.cpp: -------------------------------------------------------------------------------- 1 | #include "DRNG.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define DRNG_SUPPORT_UNKNOWN -1 10 | #define DRNG_SUPPORT_NONE 0 11 | #define DRNG_SUPPORT_RDRAND 0x01 12 | #define DRNG_SUPPORT_RDSEED 0x02 13 | 14 | #define HAVE_RDRAND ((_drng_support & DRNG_SUPPORT_RDRAND)==DRNG_SUPPORT_RDRAND) 15 | #define HAVE_RDSEED ((_drng_support & DRNG_SUPPORT_RDSEED)==DRNG_SUPPORT_RDSEED) 16 | 17 | #ifdef __ICL 18 | #define COMPILER_HAS_RDSEED_SUPPORT 1 19 | #else 20 | # if _MSC_VER >= 1800 21 | # define COMPILER_HAS_RDSEED_SUPPORT 1 22 | # endif 23 | #endif 24 | 25 | static int _drng_support= DRNG_SUPPORT_UNKNOWN; 26 | 27 | DRNG::DRNG(void) 28 | { 29 | int info[4]; 30 | 31 | if (_drng_support != DRNG_SUPPORT_UNKNOWN) return; 32 | 33 | _drng_support= DRNG_SUPPORT_NONE; 34 | 35 | // Check our feature support 36 | 37 | __cpuid(info, 0); 38 | 39 | if ( memcmp(&(info[1]), "Genu", 4) || 40 | memcmp(&(info[3]), "ineI", 4) || 41 | memcmp(&(info[2]), "ntel", 4) ) return; 42 | 43 | __cpuidex(info, 1, 0); 44 | 45 | if ( ((UINT) info[2]) & (1<<30) ) _drng_support|= DRNG_SUPPORT_RDRAND; 46 | 47 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 48 | __cpuidex(info, 7, 0); 49 | 50 | if ( ((UINT) info[1]) & (1<<18) ) _drng_support|= DRNG_SUPPORT_RDSEED; 51 | #endif 52 | } 53 | 54 | DRNG::~DRNG(void) 55 | { 56 | } 57 | 58 | int DRNG::have_rdrand () 59 | { 60 | return HAVE_RDRAND; 61 | } 62 | 63 | int DRNG::have_rdseed () 64 | { 65 | return HAVE_RDSEED; 66 | } 67 | 68 | int DRNG::random (ULONGLONG max, ULONGLONG *rand) 69 | { 70 | UINT bits; 71 | int retries= 1000; // A big enough number make failure extremely unlikely. 72 | 73 | if ( ! HAVE_RDRAND ) return 0; 74 | 75 | if ( max == 0 ) { 76 | *rand= 0; 77 | return 1; 78 | } 79 | 80 | bits= ceiling_log2(max); 81 | 82 | if ( bits > 32 ) { 83 | ULONG64 val; 84 | 85 | while (retries--) { 86 | if ( ! rand64(&val) ) return 0; 87 | 88 | val>>= (64-bits); 89 | 90 | if ( val < max ) { 91 | *rand= (ULONGLONG) val; 92 | return 1; 93 | } 94 | } 95 | } else { 96 | ULONG32 val; 97 | 98 | while (retries--) { 99 | if ( ! rand32(&val) ) return 0; 100 | 101 | val>>= (32-bits); 102 | 103 | if ( val < max ) { 104 | *rand= (ULONGLONG) val; 105 | return 1; 106 | } 107 | } 108 | } 109 | 110 | // Keep the compiler from complaining. 111 | return 0; 112 | } 113 | 114 | ULONG DRNG::get_rand_bytes (void *buf, ULONG n) 115 | { 116 | ULONG count= 0; 117 | BYTE rand[8]; 118 | PBYTE pb= (PBYTE) buf; 119 | #ifdef _WIN64 120 | ULONG blocks= int(n/8); 121 | 122 | if ( ! HAVE_RDRAND ) return 0; 123 | 124 | count= get_n_rand64((ULONG64 *) pb, blocks, 100*blocks); 125 | if ( count < blocks ) return count*8; 126 | else count*= 8; 127 | pb+= blocks*8; 128 | #else 129 | ULONG blocks= int(n/4); 130 | 131 | count= get_n_rand32((ULONG32 *) pb, blocks, 200*blocks); 132 | if ( count < blocks ) return count*4; 133 | else count*= 4; 134 | pb+= blocks*4; 135 | #endif 136 | 137 | if ( ! rand64((ULONG64 *) rand) ) return count; 138 | memcpy(pb, rand, (n-count)); 139 | 140 | return n; 141 | } 142 | 143 | ULONG DRNG::get_seed_bytes (void *buf, ULONG n) 144 | { 145 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 146 | ULONG count= 0; 147 | BYTE seed[8]; 148 | PBYTE pb= (PBYTE) buf; 149 | ULONG blocks; 150 | 151 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, n); 152 | 153 | # ifdef _WIN64 154 | blocks= int(n/8); 155 | count= get_n_seed64((ULONG64 *) pb, blocks, 100*blocks); 156 | if ( count < blocks ) return count*8; 157 | else count*= 8; 158 | pb+= blocks*8; 159 | # else 160 | blocks= int(n/4); 161 | count= get_n_seed32((ULONG32 *) pb, blocks, 200*blocks); 162 | if ( count < blocks ) return count*4; 163 | else count*= 4; 164 | pb+= blocks*4; 165 | # endif 166 | 167 | if ( ! seed64((ULONG64 *) seed) ) return count; 168 | memcpy(pb, seed, (n-count)); 169 | 170 | return n; 171 | #else 172 | return seed_from_rdrand(buf, n); 173 | #endif 174 | } 175 | 176 | //----------------------------------------------- 177 | // RDRAND internal methods 178 | //----------------------------------------------- 179 | 180 | int DRNG::rand32 (ULONG32 *rand) 181 | { 182 | int retries= 10; 183 | 184 | if ( ! HAVE_RDRAND ) return 0; 185 | 186 | while (retries--) if ( _rdrand32_step(rand) ) return 1; 187 | 188 | return 0; 189 | } 190 | 191 | int DRNG::rand64 (ULONG64 *rand) 192 | { 193 | int retries= 10; 194 | 195 | if ( ! HAVE_RDRAND ) return 0; 196 | 197 | #ifdef _WIN64 198 | while (retries--) if ( _rdrand64_step(rand) ) return 1; 199 | #else 200 | if ( get_n_rand32((ULONG32 *)rand, 2, 20) == 2 ) return 1; 201 | #endif 202 | 203 | return 0; 204 | } 205 | 206 | ULONG DRNG::get_n_rand32 (ULONG32 *buf, ULONG n, ULONG retries) 207 | { 208 | ULONG count= 0; 209 | 210 | if ( ! HAVE_RDRAND ) return 0; 211 | 212 | while (n) { 213 | if ( _rdrand32_step(buf) ) { 214 | --n; 215 | ++buf; 216 | ++count; 217 | } else { 218 | if ( ! retries ) return count; 219 | retries--; 220 | } 221 | } 222 | 223 | return count; 224 | } 225 | 226 | ULONG DRNG::get_n_rand64 (ULONG64 *buf, ULONG n, ULONG retries) 227 | { 228 | ULONG count= 0; 229 | 230 | if ( ! HAVE_RDRAND ) return 0; 231 | #ifdef _WIN64 232 | 233 | while (n) { 234 | if ( _rdrand64_step(buf) ) { 235 | --n; 236 | ++buf; 237 | ++count; 238 | } else { 239 | if ( ! retries ) return count; 240 | retries--; 241 | } 242 | } 243 | 244 | return count; 245 | #else 246 | count= get_n_rand32((ULONG32 *) buf, n, retries); 247 | if ( count == n ) { 248 | count= get_n_rand32((ULONG32 *)(buf)+count, n, retries); 249 | if ( count == n ) return n; 250 | return n/2 + int(count/2); 251 | } 252 | 253 | return int(count/2); 254 | #endif 255 | } 256 | 257 | //----------------------------------------------- 258 | // RDSEED internal methods 259 | //----------------------------------------------- 260 | 261 | int DRNG::seed32 (ULONG32 *seed) 262 | { 263 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 264 | int retries= 100; 265 | 266 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(seed, 4); 267 | 268 | while (retries--) { 269 | if ( _rdseed32_step(seed) ) return 1; 270 | _mm_pause(); 271 | } 272 | 273 | return 0; 274 | #else 275 | return seed_from_rdrand(seed, 4); 276 | #endif 277 | } 278 | 279 | int DRNG::seed64 (ULONG64 *seed) 280 | { 281 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 282 | int retries= 100; 283 | 284 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(seed, 8); 285 | 286 | # ifdef _WIN64 287 | while (retries--) { 288 | if ( _rdseed64_step(seed) ) return 1; 289 | _mm_pause(); 290 | } 291 | # else 292 | if ( get_n_seed32((ULONG32 *)seed, 2, 2*retries) == 2 ) return 1; 293 | # endif 294 | 295 | return 0; 296 | #else 297 | return seed_from_rdrand(seed, 8); 298 | #endif 299 | } 300 | 301 | ULONG DRNG::get_n_seed32 (ULONG32 *buf, ULONG n, ULONG retries) 302 | { 303 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 304 | ULONG count= 0; 305 | 306 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, 4*n); 307 | 308 | while (n) { 309 | if ( _rdseed32_step(buf) ) { 310 | --n; 311 | ++buf; 312 | ++count; 313 | } else { 314 | if ( ! retries ) return count; 315 | retries--; 316 | } 317 | _mm_pause(); 318 | } 319 | 320 | return count; 321 | #else 322 | return seed_from_rdrand(buf, 4*n); 323 | #endif 324 | } 325 | 326 | ULONG DRNG::get_n_seed64 (ULONG64 *buf, ULONG n, ULONG retries) 327 | { 328 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 329 | ULONG count= 0; 330 | 331 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, 8*n); 332 | 333 | # ifdef _WIN64 334 | while (n) { 335 | if ( _rdseed64_step(buf) ) { 336 | --n; 337 | ++buf; 338 | ++count; 339 | } else { 340 | if ( ! retries ) return count; 341 | retries--; 342 | } 343 | _mm_pause(); 344 | } 345 | 346 | return count; 347 | # else 348 | count= get_n_seed32((ULONG32 *) buf, n, retries); 349 | if ( count == n ) { 350 | count= get_n_seed32((ULONG32 *)(buf)+count, n, retries); 351 | if ( count == n ) return n; 352 | return n/2 + int(count/2); 353 | } 354 | 355 | return int(count/2); 356 | # endif 357 | #else 358 | return seed_from_rdrand(buf, 8*n); 359 | #endif 360 | } 361 | 362 | ULONG DRNG::seed_from_rdrand (void *buf, ULONG n) 363 | { 364 | // Use CBC-MAC mode of AES to generate 128-bit seeds from RDRAND. This is expensive 365 | // but if we don't have RDSEED this is our only option. 366 | // 367 | // The DRNG is guaranteed to reseed after 512 128-bit samples have been generated. 368 | 369 | BYTE key[16], iv[16], rand[16*512]; 370 | BCRYPT_ALG_HANDLE halgo; 371 | BCRYPT_KEY_HANDLE hkey; 372 | NTSTATUS status; 373 | PBYTE bp= (PBYTE) buf; 374 | ULONG count= 0; 375 | 376 | // Create an ephemeral key 377 | 378 | if ( get_n_rand64((ULONG64 *) key, 2, 20) != 2 ) return 0; 379 | 380 | // Set up encryption 381 | 382 | status= BCryptOpenAlgorithmProvider(&halgo, BCRYPT_AES_ALGORITHM, NULL, 0); 383 | if ( status != STATUS_SUCCESS ) return 0; 384 | 385 | status= BCryptGenerateSymmetricKey(halgo, &hkey, NULL, 0, (PBYTE) key, 16, 0); 386 | if ( status != STATUS_SUCCESS ) return 0; 387 | 388 | status= BCryptSetProperty(halgo, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, 389 | sizeof(BCRYPT_CHAIN_MODE_CBC), 0); 390 | if ( status != STATUS_SUCCESS ) return 0; 391 | 392 | while ( n ) { 393 | ULONG len= 0; 394 | ULONG chunk= ( n >= 16 ) ? 16 : n; 395 | 396 | // Fill our buffer with RDRAND values. 397 | if ( get_n_rand64((ULONG64 *) rand, 1024, 10240) != 1024 ) { 398 | // Error 399 | goto cleanup; 400 | } 401 | 402 | // CBC-MAC mode is a CBC encryption with a 0 IV on the plaintext. 403 | 404 | status= BCryptEncrypt(hkey, (PBYTE) rand, 512*16, NULL, NULL, 0, (PBYTE) rand, 512*16, &len, 0); 405 | if ( status != STATUS_SUCCESS || len != 512*16 ) { 406 | // Error 407 | goto cleanup; 408 | } 409 | 410 | // The last ciphertext block is the MAC. 411 | memcpy(bp, &rand[511*16], chunk); 412 | bp+= chunk; 413 | n-= chunk; 414 | count+= chunk; 415 | } 416 | 417 | cleanup: 418 | BCryptDestroyKey(hkey); 419 | BCryptCloseAlgorithmProvider(halgo, 0); 420 | 421 | return count; 422 | } 423 | 424 | // Fast ceiling of log base 2 425 | // http://stackoverflow.com/questions/3272424/compute-fast-log-base-2-ceiling 426 | // Question asked by: kevinlawler (http://stackoverflow.com/users/365478/kevinlawler) 427 | // Answered by: dgobbi (http://stackoverflow.com/users/2154690/dgobbi) 428 | // Licensed under http://creativecommons.org/licenses/by-sa/3.0/ 429 | // Changes to variable names only. [-JM] 430 | 431 | int DRNG::ceiling_log2 (ULONGLONG n) 432 | { 433 | static const ULONGLONG t[] = { 434 | 0xFFFFFFFF00000000ull, 435 | 0x00000000FFFF0000ull, 436 | 0x000000000000FF00ull, 437 | 0x00000000000000F0ull, 438 | 0x000000000000000Cull, 439 | 0x0000000000000002ull 440 | }; 441 | int i, j, k, m; 442 | 443 | j= 32; 444 | m= (((n&(n-1))==0) ? 0 : 1); 445 | 446 | for (i= 0; i< 6; ++i) { 447 | k= (((n&t[i])==0) ? 0 : j); 448 | m+= k; 449 | n>>= k; 450 | j>>= 1; 451 | } 452 | 453 | return m; 454 | } -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/DRNG.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class DRNG; 6 | 7 | typedef class DRNG DRNG; 8 | 9 | class DRNG 10 | { 11 | int rand32 (ULONG32 *rand); 12 | int rand64 (ULONG64 *rand); 13 | ULONG get_n_rand32 (ULONG32 *buf, ULONG n, ULONG retries); 14 | ULONG get_n_rand64 (ULONG64 *buf, ULONG n, ULONG retries); 15 | 16 | int seed32 (ULONG32 *seed); 17 | int seed64 (ULONG64 *seed); 18 | ULONG get_n_seed32 (ULONG32 *buf, ULONG n, ULONG retries); 19 | ULONG get_n_seed64 (ULONG64 *buf, ULONG n, ULONG retries); 20 | 21 | ULONG seed_from_rdrand (void *buf, ULONG n); 22 | 23 | int ceiling_log2 (ULONGLONG n); 24 | 25 | public: 26 | DRNG(void); 27 | ~DRNG(void); 28 | 29 | int have_rdrand(void); 30 | int have_rdseed(void); 31 | 32 | // General purpose random numbers 0 <= r < max 33 | 34 | int random (ULONGLONG max, ULONGLONG *rand); 35 | 36 | // Random seeds, suitable for static encryption keys and seeding 37 | // other PRNGs. 38 | 39 | ULONG get_seed_bytes (void *buf, ULONG n); 40 | ULONG get_rand_bytes (void *buf, ULONG n); 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : passwordManagerApp Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this passwordManagerApp application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your passwordManagerApp application. 9 | 10 | 11 | passwordManagerApp.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | passwordManagerApp.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | passwordManagerApp.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named passwordManagerApp.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/SGXWrapper.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Intel Corporation. 2 | // 3 | // The source code, information and material ("Material") contained herein is owned by 4 | // Intel Corporation or its suppliers or licensors, and title to such Material remains 5 | // with Intel Corporation or its suppliers or licensors. The Material contains 6 | // proprietary information of Intel or its suppliers and licensors. The Material is 7 | // protected by worldwide copyright laws and treaty provisions. No part of the 8 | // Material may be used, copied, reproduced, modified, published, uploaded, posted, 9 | // transmitted, distributed or disclosed in any way without Intel's prior express 10 | // written permission. No license under any patent, copyright or other intellectual 11 | // property rights in the Material is granted to or conferred upon you, either 12 | // expressly, by implication, inducement, estoppel or otherwise. Any license under 13 | // such intellectual property rights must be express and approved by Intel in writing. 14 | // 15 | // Unless otherwise agreed by Intel in writing, you may not remove or alter this 16 | // notice or any other notice embedded in Materials by Intel or Intel's suppliers or 17 | // licensors in any way. 18 | 19 | #include "stdafx.h" 20 | #include "SGXWrapper.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | SGXWrapper::SGXWrapper () 29 | { 30 | sgx_support= SGX_SUPPORT_UNKNOWN; 31 | h_urts= NULL; 32 | h_service= NULL; 33 | fp_sgx_enable_device= NULL; 34 | } 35 | 36 | SGXWrapper::~SGXWrapper () 37 | { 38 | if ( h_urts != NULL ) FreeLibrary(h_urts); 39 | if ( h_service != NULL ) FreeLibrary(h_service); 40 | } 41 | 42 | UINT SGXWrapper::get_sgx_support () 43 | { 44 | check_sgx_support(); 45 | return sgx_support; 46 | } 47 | 48 | int SGXWrapper::is_enabled () 49 | { 50 | check_sgx_support(); 51 | return (sgx_support & (SGX_SUPPORT_YES|SGX_SUPPORT_ENABLED)) ? 1 : 0; 52 | } 53 | 54 | int SGXWrapper::is_supported () 55 | { 56 | check_sgx_support(); 57 | return (sgx_support & SGX_SUPPORT_YES) ? 1 : 0; 58 | } 59 | 60 | int SGXWrapper::reboot_required () 61 | { 62 | check_sgx_support(); 63 | return (sgx_support & (SGX_SUPPORT_YES|SGX_SUPPORT_REBOOT_REQUIRED)) ? 1 : 0; 64 | } 65 | 66 | int SGXWrapper::bios_enable_required () 67 | { 68 | check_sgx_support(); 69 | return (sgx_support & (SGX_SUPPORT_YES|SGX_SUPPORT_ENABLE_REQUIRED)) ? 1 : 0; 70 | } 71 | 72 | // Private methods 73 | 74 | void SGXWrapper::check_sgx_support () 75 | { 76 | sgx_device_status_t sgx_device_status; 77 | 78 | if ( sgx_support != SGX_SUPPORT_UNKNOWN ) return; 79 | 80 | sgx_support= SGX_SUPPORT_NO; 81 | 82 | // Check for the PSW 83 | 84 | if ( ! is_psw_installed() ) return; 85 | 86 | sgx_support= SGX_SUPPORT_YES; 87 | 88 | // Try to enable SGX 89 | 90 | if ( this->enable_device(&sgx_device_status) != SGX_SUCCESS ) return; 91 | 92 | // If SGX isn't enabled yet, perform the software opt-in/enable. 93 | 94 | if ( sgx_device_status != SGX_ENABLED ) { 95 | switch (sgx_device_status) { 96 | case SGX_DISABLED_REBOOT_REQUIRED: 97 | // A reboot is required. 98 | sgx_support|= SGX_SUPPORT_REBOOT_REQUIRED; 99 | break; 100 | case SGX_DISABLED_LEGACY_OS: 101 | // BIOS enabling is required 102 | sgx_support|= SGX_SUPPORT_ENABLE_REQUIRED; 103 | break; 104 | } 105 | 106 | return; 107 | } 108 | 109 | sgx_support|= SGX_SUPPORT_ENABLED; 110 | } 111 | 112 | // Is the PSW (Platform Software) installed? 113 | 114 | int SGXWrapper::is_psw_installed () 115 | { 116 | _TCHAR *systemdir; 117 | UINT rv, sz; 118 | 119 | // Get the system directory path. Start by finding out how much space we need 120 | // to hold it. 121 | 122 | sz= GetSystemDirectory(NULL, 0); 123 | if ( sz == 0 ) return 0; 124 | 125 | systemdir= new _TCHAR[sz+1]; 126 | rv= GetSystemDirectory(systemdir, sz); 127 | if ( rv == 0 || rv > sz ) return 0; 128 | 129 | // Set our DLL search path to just the System directory so we don't accidentally 130 | // load the DLLs from an untrusted path. 131 | 132 | if ( SetDllDirectory(systemdir) == 0 ) { 133 | delete systemdir; 134 | return 0; 135 | } 136 | 137 | delete systemdir; // No longer need this 138 | 139 | // Need to be able to load both of these DLLs from the System directory. 140 | 141 | if ( (h_service= LoadLibrary(_T("sgx_uae_service.dll"))) == NULL ) { 142 | return 0; 143 | } 144 | 145 | if ( (h_urts= LoadLibrary(_T("sgx_urts.dll"))) == NULL ) { 146 | FreeLibrary(h_service); 147 | h_service= NULL; 148 | return 0; 149 | } 150 | 151 | load_functions(); 152 | 153 | return 1; 154 | } 155 | 156 | void SGXWrapper::load_functions () 157 | { 158 | fp_sgx_enable_device= (fp_sgx_enable_device_t) GetProcAddress(h_service, "sgx_enable_device"); 159 | } 160 | 161 | // Wrappers around SDK functions so the user doesn't have to mess with dynamic loading by hand. 162 | 163 | sgx_status_t SGXWrapper::enable_device(sgx_device_status_t *device_status) 164 | { 165 | check_sgx_support(); 166 | 167 | if ( fp_sgx_enable_device == NULL ) { 168 | return SGX_ERROR_UNEXPECTED; 169 | } 170 | 171 | return fp_sgx_enable_device(device_status); 172 | } -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/SGXWrapper.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Intel Corporation. 2 | // 3 | // The source code, information and material ("Material") contained herein is owned by 4 | // Intel Corporation or its suppliers or licensors, and title to such Material remains 5 | // with Intel Corporation or its suppliers or licensors. The Material contains 6 | // proprietary information of Intel or its suppliers and licensors. The Material is 7 | // protected by worldwide copyright laws and treaty provisions. No part of the 8 | // Material may be used, copied, reproduced, modified, published, uploaded, posted, 9 | // transmitted, distributed or disclosed in any way without Intel's prior express 10 | // written permission. No license under any patent, copyright or other intellectual 11 | // property rights in the Material is granted to or conferred upon you, either 12 | // expressly, by implication, inducement, estoppel or otherwise. Any license under 13 | // such intellectual property rights must be express and approved by Intel in writing. 14 | // 15 | // Unless otherwise agreed by Intel in writing, you may not remove or alter this 16 | // notice or any other notice embedded in Materials by Intel or Intel's suppliers or 17 | // licensors in any way. 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | #define SGX_SUPPORT_UNKNOWN 0x00000000 28 | #define SGX_SUPPORT_NO 0x80000000 29 | #define SGX_SUPPORT_YES 0x00000001 30 | #define SGX_SUPPORT_ENABLED 0x00000002 31 | #define SGX_SUPPORT_REBOOT_REQUIRED 0x00000004 32 | #define SGX_SUPPORT_ENABLE_REQUIRED 0x00000008 33 | 34 | // Needed for dynamic loading sanity 35 | 36 | typedef sgx_status_t (SGXAPI *fp_sgx_enable_device_t)(sgx_device_status_t *); 37 | 38 | class SGXWrapper; 39 | typedef class SGXWrapper SGXWrapper; 40 | 41 | class SGXWrapper { 42 | private: 43 | UINT sgx_support; 44 | HINSTANCE h_urts, h_service; 45 | 46 | // Function pointers 47 | 48 | fp_sgx_enable_device_t fp_sgx_enable_device; 49 | 50 | int is_psw_installed (void); 51 | void check_sgx_support (void); 52 | void load_functions (void); 53 | 54 | public: 55 | SGXWrapper(); 56 | ~SGXWrapper(); 57 | 58 | UINT get_sgx_support (void); 59 | int is_enabled (void); 60 | int is_supported (void); 61 | int reboot_required (void); 62 | int bios_enable_required (void); 63 | 64 | // Wrappers around SGX functions 65 | 66 | sgx_status_t enable_device(sgx_device_status_t *device_status); 67 | 68 | }; 69 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/passwordManagerApp.cpp: -------------------------------------------------------------------------------- 1 | // passwordManagerApp.cpp : Defines the entry point for the console application. 2 | // 3 | 4 | #include "stdafx.h" 5 | #include "passwordManagerEnclave_u.h" 6 | #include "sgx_urts.h" 7 | #include 8 | #include 9 | #include "sgx_capable.h" 10 | #include "sgx_uae_service.h" 11 | #include "sgx_tcrypto.h" 12 | 13 | #define ENCLAVE_FILE _T("passwordManagerEnclave.signed.dll") 14 | #define MAX_BUF_LEN 100 15 | 16 | using namespace std; 17 | 18 | sgx_enclave_id_t enclaveId = NULL; 19 | sgx_launch_token_t token = {0}; 20 | int updated; 21 | 22 | 23 | bool authenticate(char *username, char *password) 24 | { 25 | int ret = -1; 26 | authenticate(enclaveId,&ret,username,password,MAX_BUF_LEN); 27 | if(ret < 0) return false; 28 | return true; 29 | } 30 | 31 | bool decrypt(string *password) 32 | { 33 | //do crypto stuff 34 | return true; 35 | } 36 | 37 | bool destroyEnclave() 38 | { 39 | if(sgx_destroy_enclave(enclaveId) != SGX_SUCCESS) 40 | //printf("Error %x: cant destroy enclave\n", ret); 41 | return false; 42 | return true; 43 | } 44 | 45 | bool destroyEnclave(sgx_enclave_id_t id) 46 | { 47 | if(sgx_destroy_enclave(id) != SGX_SUCCESS) 48 | return false; 49 | return true; 50 | } 51 | 52 | 53 | bool encrypt(string *password) 54 | { 55 | //do crypto stuff 56 | return true; 57 | } 58 | 59 | 60 | 61 | int getSize() 62 | { 63 | int size; 64 | return getSize(enclaveId); 65 | return size; 66 | } 67 | 68 | bool initializeEnclave() 69 | { 70 | if(sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, 71 | &enclaveId, NULL) != SGX_SUCCESS) 72 | //printf("Error %#x: cannot create enclave\n", ret); 73 | return false; 74 | return true; 75 | } 76 | 77 | bool initializeEnclave(sgx_enclave_id_t *id) 78 | { 79 | if(sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, 80 | id, NULL) != SGX_SUCCESS) 81 | return false; 82 | return true; 83 | } 84 | 85 | //main function used to debug/demo enclave without GUI 86 | int main() 87 | { 88 | sgx_status_t ret = SGX_SUCCESS; 89 | int retval, option=1; 90 | char *username, *password, *input; 91 | 92 | /*if(sgx_is_capable(&updated) != SGX_ENABLED) 93 | { 94 | printf("Error %#x: SGX is not enabled on this device\n", ret); 95 | return -1; 96 | } 97 | */ 98 | 99 | username = (char*)malloc(MAX_BUF_LEN*sizeof(char)); 100 | password = (char*)malloc(MAX_BUF_LEN*sizeof(char)); 101 | input = (char*)malloc(MAX_BUF_LEN*sizeof(char)); 102 | 103 | if(!initializeEnclave()) 104 | { 105 | printf("Error %#x: cannot create enclave\n", ret); 106 | return -1; 107 | } 108 | 109 | 110 | //convert to GUI buttons 111 | while(option != 0) 112 | { 113 | cout << "OPTIONS:\n1 - Add User\n2 - Add account\n3 - Add URL\n"; 114 | cout << "4 - Get Password\n5 - Get Account\n6 - Get URL\n"; 115 | cout << "7 - Remove User\n0 - Quit\n" << endl; 116 | scanf_s("%i",&option); 117 | 118 | switch(option) 119 | { 120 | case 1: 121 | cout << "\nusername: "; 122 | cin >> username; 123 | cout << "password: "; 124 | cin >> password; 125 | addUser(enclaveId,&retval,username,password,MAX_BUF_LEN); 126 | if(retval < 0) 127 | cout << "Failed to add user: " << username << endl; 128 | continue; 129 | case 2: 130 | cout << "\nusername: "; 131 | cin >> username; 132 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 133 | if(retval < 0) 134 | { 135 | cout << username << " does not exist." << endl; 136 | continue; 137 | } 138 | cout << "account: "; 139 | cin >> input; 140 | setAccount(enclaveId,&retval,username,input,MAX_BUF_LEN); 141 | if(retval < 0) 142 | cout << "Failed to add account info for " << username << endl; 143 | continue; 144 | case 3: 145 | cout << "\nusername: "; 146 | cin >> username; 147 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 148 | if(retval < 0) 149 | { 150 | cout << username << " does not exist." << endl; 151 | continue; 152 | } 153 | cout << "URL: "; 154 | cin >> input; 155 | setUrl(enclaveId,&retval,username,input,MAX_BUF_LEN); 156 | if(retval < 0) 157 | cout << "Failed to add url for " << username << endl; 158 | continue; 159 | case 4: 160 | cout << "\nusername: "; 161 | cin >> username; 162 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 163 | if(retval < 0) 164 | { 165 | cout << username << " does not exist." << endl; 166 | continue; 167 | } 168 | getPassword(enclaveId,&retval,username,MAX_BUF_LEN); 169 | cout << username << endl; 170 | continue; 171 | case 5: 172 | cout << "\nusername: "; 173 | cin >> username; 174 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 175 | if(retval < 0) 176 | { 177 | cout << username << " does not exist." << endl; 178 | continue; 179 | } 180 | getAccount(enclaveId,&retval,username,MAX_BUF_LEN); 181 | cout << username << endl; 182 | continue; 183 | case 6: 184 | cout << "\nusername: "; 185 | cin >> username; 186 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 187 | if(retval < 0) 188 | { 189 | cout << username << " does not exist." << endl; 190 | continue; 191 | } 192 | getUrl(enclaveId,&retval,username,MAX_BUF_LEN); 193 | cout << username << endl; 194 | continue; 195 | case 7: 196 | cout << "\nusername: "; 197 | cin >> username; 198 | findUser(enclaveId,&retval,username,MAX_BUF_LEN); 199 | if(retval < 0) 200 | { 201 | cout << username << " does not exist." << endl; 202 | continue; 203 | } 204 | removeUser(enclaveId,&retval,username,MAX_BUF_LEN); 205 | continue; 206 | 207 | default: 208 | printf("Invalid option.\n"); 209 | continue; 210 | 211 | } 212 | 213 | 214 | 215 | } 216 | 217 | 218 | 219 | 220 | if(!destroyEnclave()) 221 | { 222 | printf("Error %x: cant destroy enclave\n", ret); 223 | return -1; 224 | } 225 | 226 | 227 | return 0; 228 | } 229 | 230 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/passwordManagerApp.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {BA553623-C2EE-4FD0-9FE0-17CEF25B5B45} 15 | Win32Proj 16 | passwordManagerApp 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | Use 51 | Level3 52 | Disabled 53 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 54 | true 55 | $(SGXSDKInstallPath)\include;%(AdditionalIncludeDirectories) 56 | 57 | 58 | Console 59 | true 60 | $(SGXSDKInstallPath)\bin\$(Platform)\Debug;%(AdditionalLibraryDirectories) 61 | sgx_urts.lib;sgx_uae_service.lib;%(AdditionalDependencies) 62 | 63 | 64 | 65 | 66 | Level3 67 | Use 68 | MaxSpeed 69 | true 70 | true 71 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 72 | true 73 | $(SGXSDKInstallPath)\include;%(AdditionalIncludeDirectories) 74 | 75 | 76 | Console 77 | true 78 | true 79 | true 80 | $(SGXSDKInstallPath)\bin\$(Platform)\Release;%(AdditionalLibraryDirectories) 81 | sgx_urts.lib;sgx_uae_service.lib;%(AdditionalDependencies) 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Create 108 | Create 109 | 110 | 111 | 112 | 113 | "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" --untrusted ".\..\..\passwordManagerEnclave\passwordManagerEnclave\passwordManagerEnclave.edl" --search-path ".\..\..\passwordManagerEnclave\passwordManagerEnclave%3b$(SGXSDKInstallPath)\include" 114 | Creating untrusted proxy/bridge routines 115 | $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) 116 | "$(SGXSDKInstallPath)\bin\win32\Release\sgx_edger8r.exe" --untrusted ".\..\..\passwordManagerEnclave\passwordManagerEnclave\passwordManagerEnclave.edl" --search-path ".\..\..\passwordManagerEnclave\passwordManagerEnclave%3b$(SGXSDKInstallPath)\include" 117 | Creating untrusted proxy/bridge routines 118 | $(ProjectDir)%(Filename)_u.h;$(ProjectDir)%(Filename)_u.c;%(Outputs) 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/passwordManagerApp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {6991c89c-b695-42e4-9525-66b75b6fc282} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Generated Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | 44 | 45 | Source Files 46 | 47 | 48 | Source Files 49 | 50 | 51 | Generated Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files 61 | 62 | 63 | 64 | 65 | Source Files 66 | 67 | 68 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/passwordManagerEnclave.signed.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IntelSoftware/Tutorial-Password-Manager-with-Intel-SGX/0071bccef06791ddbffb61d6827f0957c143c578/passwordManager/passwordManagerApp/passwordManagerApp/passwordManagerEnclave.signed.dll -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // passwordManagerApp.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/CryptoTests.cpp: -------------------------------------------------------------------------------- 1 | // Tests for the Crypto module 2 | 3 | #pragma comment(lib, "Bcrypt.lib") 4 | 5 | #include "stdafx.h" 6 | #include "windows.h" 7 | #include "..\..\Crypto.h" 8 | #include 9 | #include 10 | 11 | int test_result(int); 12 | int test_salt(Crypto *crypto, PBYTE salt); 13 | int test_kdf (Crypto *crypto, PBYTE passphrase, DWORD passphrase_len, PBYTE salt, PBYTE master_key); 14 | int test_db_key(Crypto *crypto, PBYTE db_key); 15 | int test_key_encryption(Crypto *crypto, PBYTE db_key, PBYTE master_key); 16 | 17 | int db_key_callback(int count, int need); 18 | 19 | void hexdump (const PBYTE data, DWORD len, BOOL addresses); 20 | int hexval (const BYTE ch, PBYTE val); 21 | int pack (PBYTE hex, const PBYTE ascii, ULONG len); 22 | void Exit (int code); 23 | 24 | static const BYTE initbytes[]= { 25 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 26 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 27 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 28 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 29 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 30 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 31 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D, 32 | 0xDE, 0xAD, 0x8B, 0xAD, 0xCA, 0xFE, 0xF0, 0x0D 33 | }; 34 | 35 | #define PASSPHRASE "This is my test passphrase and I h0pe you like it." 36 | 37 | int _tmain(int argc, _TCHAR* argv[]) 38 | { 39 | Crypto crypto; 40 | BYTE salt[CRYPTO_KDF_SALT_LEN]; 41 | BYTE master_key[16], db_key[16]; 42 | int pass= 0; 43 | int tests= 4; 44 | 45 | pass+= test_result( 46 | test_salt(&crypto, (PBYTE) salt) 47 | ); 48 | 49 | pass+= test_result( 50 | test_db_key(&crypto, db_key) 51 | ); 52 | 53 | pass+= test_result( 54 | test_kdf(&crypto, (PBYTE) PASSPHRASE, sizeof(PASSPHRASE), salt, master_key) 55 | ); 56 | 57 | pass+= test_result( 58 | test_key_encryption(&crypto, db_key, master_key) 59 | ); 60 | 61 | if ( tests == pass ) { 62 | wprintf(L"\n===> ALL TESTS PASSED <===\n\n"); 63 | Exit(0); 64 | } 65 | 66 | wprintf(L"%d OF %d TESTS PASSING\n\n", pass, tests); 67 | Exit(1); 68 | } 69 | 70 | //---------------------------------------------------------------------------------------------------- 71 | // DB encryption/decryption test 72 | //---------------------------------------------------------------------------------------------------- 73 | 74 | int test_key_encryption(Crypto *crypto, PBYTE db_key, PBYTE master_key) 75 | { 76 | crypto_status_t status; 77 | BYTE tmkey[16], tdbkey[16], ekey[16], iv[12], authtag[16], kauthtag[16], ddb_key[16]; 78 | static const BYTE ekey_answer[]= { 0x6c, 0x7e, 0xf7, 0x29, 0x15, 0xa3, 0xe8, 0x63, 0x8b, 0xc4, 0xc7, 0x2e, 0xd9, 0x2a, 0xfc, 0x35 }; 79 | static const BYTE authtag_answer[]= { 0x88, 0xc9, 0x81, 0x29, 0xaa, 0x5a, 0x74, 0x08, 0x4d, 0xc3, 0xf5, 0x69, 0x86, 0x37, 0xa0, 0xce }; 80 | 81 | wprintf(L"DB KEY ENCRYPTION TEST\n"); 82 | 83 | // Known key encryption test 84 | 85 | memcpy(tmkey, initbytes, 16); 86 | if ( memcmp(tmkey, initbytes, 16) != 0 ) { 87 | wprintf(L"Error: Known master key initialization failed\n"); 88 | return 0; 89 | } 90 | 91 | memcpy(tdbkey, initbytes, 16); 92 | if ( memcmp(tdbkey, initbytes, 16) != 0 ) { 93 | wprintf(L"Error: Known master key initialization failed\n"); 94 | return 0; 95 | } 96 | 97 | memcpy(ekey, initbytes, 16); 98 | if ( memcmp(ekey, initbytes, 16) != 0 ) { 99 | wprintf(L"Error: Encrypted, known DB key initialization failed\n"); 100 | return 0; 101 | } 102 | 103 | memcpy(iv, initbytes, 12); 104 | if ( memcmp(iv, initbytes, 12) != 0 ) { 105 | wprintf(L"Error: Known IV key initialization failed\n"); 106 | return 0; 107 | } 108 | 109 | memcpy(authtag, initbytes, 12); 110 | if ( memcmp(authtag, initbytes, 12) != 0 ) { 111 | wprintf(L"Error: authentication tag initialization failed\n"); 112 | return 0; 113 | } 114 | 115 | wprintf(L"Known database key:\n"); 116 | hexdump(tdbkey, 16, 1); 117 | wprintf(L"Lnown master key:\n"); 118 | hexdump(tmkey, 16, 1); 119 | wprintf(L"Known IV:\n"); 120 | hexdump(iv, 12, 1); 121 | 122 | wprintf(L"Encrypting known database key with known master key...\n"); 123 | status= crypto->encrypt_database_key(tmkey, tdbkey, ekey, iv, authtag, CRYPTO_F_IV_PROVIDED); 124 | if ( status != CRYPTO_OK ) { 125 | wprintf(L"encrypt_database_key returned 0x%08x\n", status); 126 | return 0; 127 | } 128 | wprintf(L"Encrypted, known database key:\n"); 129 | hexdump(ekey, 16, 1); 130 | wprintf(L"Known auth tag:\n"); 131 | hexdump(authtag, 16, 1); 132 | 133 | if ( memcmp(ekey, ekey_answer, 16) ) { 134 | wprintf(L"Known key encryption does not match expected answer\n"); 135 | return 0; 136 | } 137 | 138 | if ( memcmp(authtag, authtag_answer, 16) ) { 139 | wprintf(L"Known key encryption auth tag does not match expected answer\n"); 140 | return 0; 141 | } 142 | 143 | // Encrypt with provided keys and random IV 144 | 145 | wprintf(L"\nEncrypting provides keys with random IV\n"); 146 | wprintf(L"Database key:\n"); 147 | hexdump(db_key, 16, 1); 148 | wprintf(L"Master key:\n"); 149 | hexdump(master_key, 16, 1); 150 | 151 | memcpy(kauthtag, initbytes, 12); 152 | if ( memcmp(kauthtag, initbytes, 12) != 0 ) { 153 | wprintf(L"Error: authentication tag initialization failed\n"); 154 | return 0; 155 | } 156 | 157 | status= crypto->encrypt_database_key(master_key, db_key, ekey, iv, kauthtag); 158 | if ( status != CRYPTO_OK ) { 159 | wprintf(L"encrypt_database_key returned 0x%08x\n", status); 160 | return 0; 161 | } 162 | wprintf(L"Encrypted, database key:\n"); 163 | hexdump(ekey, 16, 1); 164 | wprintf(L"Auth tag:\n"); 165 | hexdump(kauthtag, 16, 1); 166 | wprintf(L"IV:\n"); 167 | hexdump(iv, 12, 1); 168 | 169 | if ( memcmp(iv, initbytes, 12) == 0 ) { 170 | wprintf(L"IV not random\n"); 171 | return 0; 172 | } 173 | 174 | // Decryption 175 | 176 | memcpy(ddb_key, initbytes, 16); 177 | if ( memcmp(ddb_key, initbytes, 16) != 0 ) { 178 | wprintf(L"Error: Known master key initialization failed\n"); 179 | return 0; 180 | } 181 | 182 | wprintf(L"Decrypting encrypted master key...\n"); 183 | status= crypto->decrypt_database_key(master_key, ekey, iv, kauthtag, ddb_key); 184 | if ( status != CRYPTO_OK ) { 185 | wprintf(L"decrypt_database_key returned 0x%08x\n", status); 186 | return 0; 187 | } else { 188 | wprintf(L"decrypt_database_key OK\n", status); 189 | hexdump(ddb_key, 16, 1); 190 | } 191 | 192 | wprintf(L"Decrypt with bad master key (should fail)...\n"); 193 | status= crypto->decrypt_database_key(tmkey, ekey, iv, kauthtag, ddb_key); 194 | if ( status == CRYPTO_OK ) { 195 | wprintf(L"decrypt_database_key OK\n", status); 196 | return 0; 197 | } else { 198 | wprintf(L"decrypt_database_key FAILED\n", status); 199 | } 200 | 201 | wprintf(L"Decrypt with bad IV (should fail)...\n"); 202 | iv[2]^= 0xff; 203 | status= crypto->decrypt_database_key(master_key, ekey, iv, kauthtag, ddb_key); 204 | if ( status == CRYPTO_OK ) { 205 | wprintf(L"decrypt_database_key OK\n", status); 206 | return 0; 207 | } else { 208 | wprintf(L"decrypt_database_key FAILED\n", status); 209 | } 210 | iv[2]^= 0xff; 211 | 212 | wprintf(L"Decrypt with bad ciphertext (should fail)...\n"); 213 | ekey[15]^= 0xff; 214 | status= crypto->decrypt_database_key(master_key, ekey, iv, kauthtag, ddb_key); 215 | if ( status == CRYPTO_OK ) { 216 | wprintf(L"decrypt_database_key OK\n", status); 217 | return 0; 218 | } else { 219 | wprintf(L"decrypt_database_key FAILED\n", status); 220 | } 221 | ekey[15]^= 0xff; 222 | 223 | wprintf(L"Decrypt with bad authtag (should fail)...\n"); 224 | status= crypto->decrypt_database_key(master_key, ekey, iv, authtag, ddb_key); 225 | if ( status == CRYPTO_OK ) { 226 | wprintf(L"decrypt_database_key OK\n", status); 227 | return 0; 228 | } else { 229 | wprintf(L"decrypt_database_key FAILED\n", status); 230 | } 231 | 232 | return 1; 233 | } 234 | 235 | //---------------------------------------------------------------------------------------------------- 236 | // Key Derivation Function test 237 | //---------------------------------------------------------------------------------------------------- 238 | 239 | int test_kdf (Crypto *crypto, PBYTE passphrase, DWORD passphrase_len, PBYTE salt, PBYTE master_key) 240 | { 241 | crypto_status_t status; 242 | static const BYTE tkey_answer[]= { 0xaf, 0x4d, 0x13, 0x25, 0x08, 0x21, 0xd3, 0x03, 0xfe, 0x02, 0xaf, 0xbb, 0xbe, 0x5d, 0xcc, 0xed }; 243 | BYTE tsalt[CRYPTO_KDF_SALT_LEN]; 244 | BYTE tkey[16]; 245 | 246 | wprintf(L"KDF TEST\n"); 247 | 248 | // Known key tests 249 | 250 | memcpy(tkey, initbytes, 16); 251 | if ( memcmp(tkey, initbytes, 16) != 0 ) { 252 | wprintf(L"Error: Known key initialization failed\n"); 253 | return 0; 254 | } 255 | 256 | memcpy(tsalt, initbytes, CRYPTO_KDF_SALT_LEN); 257 | if ( memcmp(tkey, initbytes, CRYPTO_KDF_SALT_LEN) != 0 ) { 258 | wprintf(L"Error: Known salt initialization failed\n"); 259 | return 0; 260 | } 261 | 262 | if ( (status= crypto->derive_master_key(passphrase, passphrase_len, tsalt, tkey)) == CRYPTO_OK ) { 263 | wprintf(L"Known master key: \n"); 264 | hexdump(tkey, 16, 1); 265 | } else { 266 | wprintf(L"Error: derive_master_key returned 0x%08x\n", status); 267 | return 0; 268 | } 269 | 270 | wprintf(L"Expected master key: \n"); 271 | hexdump((const PBYTE) tkey_answer, 16, 1); 272 | 273 | if ( memcmp(tkey, tkey_answer, 16) ) { 274 | wprintf(L"Known key derivation test failed\n"); 275 | return 0; 276 | } 277 | memset(tkey, 0, 16); 278 | 279 | if ( (status= crypto->derive_master_key(passphrase, passphrase_len, tsalt, tkey)) == CRYPTO_OK && ! memcmp(tkey, tkey_answer, 16) ) { 280 | wprintf(L"Known master key validation OK\n"); 281 | } else { 282 | wprintf(L"Known master key validation FAILED\n"); 283 | return 0; 284 | } 285 | 286 | wprintf(L"Validating with bad passphrase (this should fail)...\n"); 287 | if ( (status= crypto->derive_master_key(passphrase, passphrase_len-1, tsalt, tkey)) == CRYPTO_OK && ! memcmp(tkey, tkey_answer, 16)) { 288 | wprintf(L"Known master key validation OK\n"); 289 | return 0; 290 | } else { 291 | wprintf(L"Known master key validation FAILED\n"); 292 | } 293 | 294 | wprintf(L"Validating with bad salt (this should fail)...\n"); 295 | tsalt[0]^= 0xFF; 296 | if ( (status= crypto->derive_master_key(passphrase, passphrase_len, tsalt, tkey)) == CRYPTO_OK && ! memcmp(tkey, tkey_answer, 16)) { 297 | wprintf(L"Known master key validation OK\n"); 298 | return 0; 299 | } else { 300 | wprintf(L"Known master key validation FAILED\n"); 301 | } 302 | tsalt[0]^= 0xFF; 303 | 304 | 305 | // Random salt, random key test 306 | 307 | if ( (status= crypto->derive_master_key(passphrase, passphrase_len, salt, master_key)) == CRYPTO_OK ) { 308 | wprintf(L"Master key: \n"); 309 | hexdump(master_key, 16, 1); 310 | } else { 311 | wprintf(L"Error: derive_master_key returned 0x%08x\n", status); 312 | return 0; 313 | } 314 | 315 | if ( memcmp(tkey, master_key, 16) == 0 ) { 316 | wprintf(L"Salted master key matches known key\n"); 317 | return 0; 318 | } 319 | 320 | return 1; 321 | } 322 | 323 | //---------------------------------------------------------------------------------------------------- 324 | // DB key generation test 325 | //---------------------------------------------------------------------------------------------------- 326 | 327 | int test_db_key(Crypto *crypto, PBYTE db_key) 328 | { 329 | BYTE tkey[16]; 330 | crypto_status_t status; 331 | 332 | wprintf(L"DATABASE KEY TEST\n"); 333 | 334 | memcpy(db_key, initbytes, 16); 335 | if ( memcmp(db_key, initbytes, 16) != 0 ) { 336 | wprintf(L"Error: database key initialization failed\n"); 337 | return 0; 338 | } 339 | hexdump(db_key, 16, 1); 340 | 341 | memcpy(tkey, initbytes, 16); 342 | if ( memcmp(tkey, initbytes, 16) != 0 ) { 343 | wprintf(L"Error: database key 2 initialization failed\n"); 344 | return 0; 345 | } 346 | hexdump(tkey, 16, 1); 347 | 348 | wprintf(L"Generating database key...\n"); 349 | if ( (status= crypto->generate_database_key(db_key, &db_key_callback)) == CRYPTO_OK ) { 350 | wprintf(L"key: "); 351 | hexdump(db_key, 16, 0); 352 | } else { 353 | wprintf(L"Error: generate_database_key returned 0x%08x\n", status); 354 | return 0; 355 | } 356 | if ( memcmp(db_key, initbytes, 16) == 0 ) { 357 | wprintf(L"Error: database key matches initialization bytes\n"); 358 | return 0; 359 | } 360 | 361 | wprintf(L"Generating database key 2...\n"); 362 | if ( (status= crypto->generate_database_key(tkey, &db_key_callback)) == CRYPTO_OK ) { 363 | wprintf(L"key 2: "); 364 | hexdump(tkey, 16, 0); 365 | } else { 366 | wprintf(L"Error: generate_database_key returned 0x%08x\n", status); 367 | return 0; 368 | } 369 | if ( memcmp(tkey, initbytes, 16) == 0 ) { 370 | wprintf(L"Error: database key 2 matches initialization bytes\n"); 371 | return 0; 372 | } 373 | 374 | if ( memcmp(db_key, tkey, 16) == 0 ) { 375 | wprintf(L"Error: keys not random\n"); 376 | return 0; 377 | } 378 | 379 | return 1; 380 | } 381 | 382 | int db_key_callback(int count, int need) 383 | { 384 | wprintf(L"...got %d of %d bytes\n", count, count); 385 | return 1; 386 | } 387 | 388 | //---------------------------------------------------------------------------------------------------- 389 | // Salt test 390 | //---------------------------------------------------------------------------------------------------- 391 | 392 | int test_salt (Crypto *crypto, PBYTE salt) 393 | { 394 | BYTE salt2[CRYPTO_KDF_SALT_LEN]; 395 | crypto_status_t status; 396 | 397 | wprintf(L"RANDOM SALT TEST\n"); 398 | 399 | memcpy(salt, initbytes, CRYPTO_KDF_SALT_LEN); 400 | if ( memcmp(salt, initbytes, CRYPTO_KDF_SALT_LEN) != 0 ) { 401 | wprintf(L"Error: salt initialization failed\n"); 402 | return 0; 403 | } 404 | hexdump(salt, CRYPTO_KDF_SALT_LEN, 1); 405 | 406 | memcpy(salt2, initbytes, CRYPTO_KDF_SALT_LEN); 407 | if ( memcmp(salt2, initbytes, CRYPTO_KDF_SALT_LEN) != 0 ) { 408 | wprintf(L"Error: salt initialization failed\n"); 409 | return 0; 410 | } 411 | hexdump(salt2, CRYPTO_KDF_SALT_LEN, 1); 412 | 413 | 414 | status= crypto->generate_salt((PBYTE) salt); 415 | if ( status == CRYPTO_OK ) { 416 | wprintf(L"salt: "); 417 | hexdump(salt, CRYPTO_KDF_SALT_LEN, 0); 418 | } else { 419 | wprintf(L"Error: generate_salt returned 0x%08x\n", status); 420 | return 0; 421 | } 422 | 423 | if ( memcmp(salt, initbytes, CRYPTO_KDF_SALT_LEN) == 0 ) { 424 | wprintf(L"Error: salt matches initialization string\n"); 425 | return 0; 426 | } 427 | 428 | if ( (status= crypto->generate_salt(salt2)) == CRYPTO_OK ) { 429 | wprintf(L"salt2: "); 430 | hexdump(salt2, CRYPTO_KDF_SALT_LEN, 0); 431 | } else { 432 | wprintf(L"Error: generate_salt returned 0x%08x\n", status); 433 | return 0; 434 | } 435 | 436 | if ( memcmp(salt2, initbytes, CRYPTO_KDF_SALT_LEN) == 0 ) { 437 | wprintf(L"Error: salt2 matches initialization string\n"); 438 | return 0; 439 | } 440 | 441 | 442 | if ( memcmp(salt, salt2, CRYPTO_KDF_SALT_LEN ) == 0 ) { 443 | wprintf(L"Error: salts not random\n"); 444 | return 0; 445 | } 446 | 447 | return 1; 448 | } 449 | 450 | 451 | void Exit (int code) 452 | { 453 | wprintf(L"Press ENTER to exit..."); 454 | getchar(); 455 | exit(code); 456 | } 457 | 458 | int pack (PBYTE hex, const PBYTE ascii, ULONG len) 459 | { 460 | ULONG i; 461 | BYTE val; 462 | PBYTE pascii= ascii; 463 | 464 | if ( len%2 ) return 0; 465 | 466 | for (i= 0; i= 0x30 && ch <= 0x39 ) { 490 | *val= ch-0x30; 491 | return 1; 492 | } else if ( ch >= 0x41 && ch <= 0x46 ) { 493 | *val= ch-0x37; 494 | return 1; 495 | } else if ( ch >= 0x61 && ch <= 0x66 ) { 496 | *val= ch-0x57; 497 | return 1; 498 | } 499 | 500 | return 0; 501 | } 502 | 503 | void hexdump (const PBYTE data, DWORD len, BOOL addresses) 504 | { 505 | DWORD i; 506 | BYTE *bp = (unsigned char *)data; 507 | 508 | if (!len) return; 509 | 510 | if (addresses) wprintf(L" 0x%08lx: ", data); 511 | 512 | for (i = 1; i <= len; ++i) { 513 | printf("%02x ", *bp++); 514 | if (!(i % 16)) { 515 | if (addresses && i != len) wprintf(L"\n 0x%08lx: ", data+i); 516 | else if ( i != len ) wprintf(L"\n"); 517 | } 518 | else if (!(i % 8)) printf(" "); 519 | } 520 | wprintf(L"\n"); 521 | } 522 | 523 | int test_result (int b) { 524 | wprintf(L"*** Result: %s ***\n\n\n", (b) ? L"PASS" : L"FAIL"); 525 | return (b) ? 1 : 0; 526 | } -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/CryptoTests.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CryptoTests", "CryptoTests.vcxproj", "{301697BE-CCAD-4FDF-8519-B28987D4086C}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {301697BE-CCAD-4FDF-8519-B28987D4086C}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {301697BE-CCAD-4FDF-8519-B28987D4086C}.Debug|Win32.Build.0 = Debug|Win32 14 | {301697BE-CCAD-4FDF-8519-B28987D4086C}.Release|Win32.ActiveCfg = Release|Win32 15 | {301697BE-CCAD-4FDF-8519-B28987D4086C}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/CryptoTests.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {301697BE-CCAD-4FDF-8519-B28987D4086C} 15 | Win32Proj 16 | CryptoTests 17 | 18 | 19 | 20 | Application 21 | true 22 | v110 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v110 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | NotUsing 51 | Level3 52 | Disabled 53 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 54 | %(AdditionalIncludeDirectories) 55 | 56 | 57 | Console 58 | true 59 | 60 | 61 | 62 | 63 | Level3 64 | Use 65 | MaxSpeed 66 | true 67 | true 68 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 69 | %(AdditionalIncludeDirectories) 70 | 71 | 72 | Console 73 | true 74 | true 75 | true 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Create 93 | Create 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/CryptoTests.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : CryptoTests Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this CryptoTests application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your CryptoTests application. 9 | 10 | 11 | CryptoTests.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | CryptoTests.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | CryptoTests.cpp 25 | This is the main application source file. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other standard files: 29 | 30 | StdAfx.h, StdAfx.cpp 31 | These files are used to build a precompiled header (PCH) file 32 | named CryptoTests.pch and a precompiled types file named StdAfx.obj. 33 | 34 | ///////////////////////////////////////////////////////////////////////////// 35 | Other notes: 36 | 37 | AppWizard uses "TODO:" comments to indicate parts of the source code you 38 | should add to or customize. 39 | 40 | ///////////////////////////////////////////////////////////////////////////// 41 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // CryptoTests.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | 15 | // TODO: reference additional headers your program requires here 16 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerApp/passwordManagerApp/tests/CryptoTests/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "passwordManagerEnclave", "passwordManagerEnclave\passwordManagerEnclave.vcxproj", "{A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Prerelease|Win32 = Prerelease|Win32 10 | Release|Win32 = Release|Win32 11 | Simulation|Win32 = Simulation|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Debug|Win32.Build.0 = Debug|Win32 16 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Prerelease|Win32.ActiveCfg = Prerelease|Win32 17 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Prerelease|Win32.Build.0 = Prerelease|Win32 18 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Release|Win32.ActiveCfg = Release|Win32 19 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Release|Win32.Build.0 = Release|Win32 20 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Simulation|Win32.ActiveCfg = Simulation|Win32 21 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8}.Simulation|Win32.Build.0 = Simulation|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/E_Crypto.cpp: -------------------------------------------------------------------------------- 1 | #include "E_Crypto.h" 2 | #include 3 | #include 4 | 5 | static void _xor_quads (void *dst, void *src, int n); 6 | 7 | E_Crypto::E_Crypto(void) 8 | { 9 | } 10 | 11 | 12 | E_Crypto::~E_Crypto(void) 13 | { 14 | } 15 | 16 | crypto_status_t E_Crypto::generate_database_key (unsigned char key_out[16], GenerateDatabaseKeyCallback callback) 17 | { 18 | unsigned long count= 0; 19 | 20 | while ( (count= drng.get_seed_bytes(&key_out[count], 16)) < 16 ) { 21 | if ( callback != NULL ) { 22 | int rv; 23 | // So that the GUI can show a progress indicator, a cancel button, etc. 24 | rv= callback(count, 16); 25 | if ( rv == 0 ) { 26 | // A zero return value from the callback means we should abort. 27 | return CRYPTO_ERR_USER_CANCEL; 28 | } 29 | } 30 | } 31 | 32 | if ( callback != NULL ) callback(16, 16); 33 | return CRYPTO_OK; 34 | } 35 | 36 | crypto_status_t E_Crypto::derive_master_key (unsigned char *passphrase, unsigned long passphrase_len, unsigned char salt[8], unsigned char key_out[16]) 37 | { 38 | return this->derive_master_key_ex(passphrase, passphrase_len, salt, 8, CRYPTO_KDF_ITERATIONS, key_out); 39 | } 40 | 41 | crypto_status_t E_Crypto::derive_master_key_ex (unsigned char *passphrase, unsigned long passphrase_len, unsigned char *salt, unsigned long salt_len, 42 | unsigned long iterations, unsigned char key_out[16]) 43 | { 44 | unsigned char *messages[3]= { passphrase, salt, NULL }; 45 | unsigned long lengths[3]= { passphrase_len, salt_len, 0 }; 46 | unsigned char msg[32], md[32], key[32]; 47 | unsigned long i; 48 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 49 | 50 | rv= this->sha256_multi(messages, lengths, md); 51 | if ( rv != CRYPTO_OK ) { 52 | return rv; 53 | } 54 | memcpy(key, md, 32); 55 | 56 | messages[1]= msg; 57 | lengths[1]= 32; 58 | 59 | for (i= 0; i< iterations; ++i) { 60 | int j; 61 | 62 | memcpy(msg, md, 32); 63 | rv= this->sha256_multi(messages, lengths, md); 64 | if ( rv != CRYPTO_OK) { 65 | return rv; 66 | } 67 | 68 | // The compiler will optimize this 69 | for (j= 0; j<32; ++j) key[j]^= md[j]; 70 | } 71 | 72 | memcpy(key_out, &(key[8]), 16); 73 | 74 | return CRYPTO_OK; 75 | } 76 | 77 | crypto_status_t E_Crypto::validate_passphrase (unsigned char * passphrase, unsigned long passphrase_len, unsigned char salt[8], 78 | unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned char db_key_pt[16]) 79 | { 80 | return this->validate_passphrase_ex(passphrase, passphrase_len, salt, CRYPTO_KDF_SALT_LEN, CRYPTO_KDF_ITERATIONS, db_key_ct, iv, tag, db_key_pt); 81 | } 82 | 83 | crypto_status_t E_Crypto::validate_passphrase_ex (unsigned char * passphrase, unsigned long passphrase_len, unsigned char * salt, unsigned long salt_len, 84 | unsigned long iterations, unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned char db_key_pt[16]) 85 | { 86 | unsigned char mkey[16]; 87 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 88 | 89 | rv= this->derive_master_key_ex(passphrase, passphrase_len, salt, salt_len, iterations, mkey); 90 | if ( rv != CRYPTO_OK ) { 91 | return rv; 92 | } 93 | 94 | rv= this->decrypt_database_key(mkey, db_key_ct, iv, tag, db_key_pt); 95 | if ( rv == CRYPTO_ERR_DECRYPT_AUTH ) return CRYPTO_ERR_PASS_MISMATCH; 96 | 97 | return rv; 98 | } 99 | 100 | crypto_status_t E_Crypto::generate_salt (unsigned char salt[8]) 101 | { 102 | return this->generate_salt_ex(salt, CRYPTO_KDF_SALT_LEN); 103 | } 104 | 105 | crypto_status_t E_Crypto::generate_salt_ex (unsigned char *salt, unsigned long salt_len) 106 | { 107 | unsigned long n= drng.get_rand_bytes(salt, salt_len); 108 | if ( n != salt_len ) { 109 | // RDRAND should not fail unless something bad has happened. 110 | return CRYPTO_ERR_DRNG; 111 | } 112 | 113 | return CRYPTO_OK; 114 | } 115 | 116 | crypto_status_t E_Crypto::generate_nonce_gcm (unsigned char *nonce) 117 | { 118 | unsigned long n= drng.get_rand_bytes(nonce, 12); 119 | if ( n != 12 ) { 120 | // RDRAND should not fail unless something bad has happened. 121 | return CRYPTO_ERR_DRNG; 122 | } 123 | 124 | return CRYPTO_OK; 125 | } 126 | 127 | crypto_status_t E_Crypto::encrypt_database_key (unsigned char master_key[16], unsigned char db_key_pt[16], unsigned char db_key_ct[16], 128 | unsigned char iv[12], unsigned char tag[16], unsigned int flags) 129 | { 130 | crypto_status_t rv; 131 | 132 | 133 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 134 | rv= this->generate_nonce_gcm(iv); 135 | if ( rv != CRYPTO_OK ) { 136 | return rv; 137 | } 138 | } 139 | 140 | return this->aes_128_gcm_encrypt(master_key, iv, 12, db_key_pt, 16, db_key_ct, tag); 141 | } 142 | 143 | crypto_status_t E_Crypto::decrypt_database_key (unsigned char master_key[16], unsigned char db_key_ct[16], unsigned char iv[12], 144 | unsigned char tag[16], unsigned char db_key_pt[16]) 145 | { 146 | return this->aes_128_gcm_decrypt(master_key, iv, 12, db_key_ct, 16, db_key_pt, tag); 147 | } 148 | 149 | crypto_status_t E_Crypto::encrypt_account_password (unsigned char db_key[16], unsigned char *password_pt, unsigned long password_len, 150 | unsigned char *password_ct, unsigned char iv[12], unsigned char tag[16], unsigned int flags) 151 | { 152 | crypto_status_t rv; 153 | 154 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 155 | rv= this->generate_nonce_gcm(iv); 156 | if ( rv != CRYPTO_OK ) { 157 | return rv; 158 | } 159 | } 160 | 161 | return this->aes_128_gcm_encrypt(db_key, iv, 12, password_pt, password_len, password_ct, tag); 162 | } 163 | 164 | crypto_status_t E_Crypto::decrypt_account_password (unsigned char db_key[16], unsigned char *password_ct, unsigned long password_len, 165 | unsigned char iv[12], unsigned char tag[16], unsigned char *password) 166 | { 167 | return this->aes_128_gcm_decrypt(db_key, iv, 12, password_ct, password_len, password, tag); 168 | } 169 | 170 | crypto_status_t E_Crypto::encrypt_database (unsigned char db_key[16], unsigned char *db_serialized, unsigned long db_size, 171 | unsigned char *db_ct, unsigned char iv[12], unsigned char tag[16], unsigned int flags) 172 | { 173 | crypto_status_t rv; 174 | 175 | if ( ! (flags & CRYPTO_F_IV_PROVIDED) ) { 176 | rv= this->generate_nonce_gcm(iv); 177 | if ( rv != CRYPTO_OK ) { 178 | return rv; 179 | } 180 | } 181 | 182 | return this->aes_128_gcm_encrypt(db_key, iv, 12, db_serialized, db_size, db_ct, tag); 183 | } 184 | 185 | crypto_status_t E_Crypto::decrypt_database (unsigned char db_key[16], unsigned char *db_ct, unsigned long db_size, 186 | unsigned char iv[12], unsigned char tag[16], unsigned char *db_serialized) 187 | { 188 | return this->aes_128_gcm_decrypt(db_key, iv, 12, db_ct, db_size, db_serialized, tag); 189 | } 190 | 191 | //------------------------------------------------------------ 192 | // Private methods 193 | //------------------------------------------------------------ 194 | 195 | crypto_status_t E_Crypto::aes_128_gcm_encrypt(unsigned char *key, unsigned char *nonce, unsigned long nonce_len, 196 | unsigned char *pt, unsigned long pt_len, unsigned char *ct, unsigned char *tag) 197 | { 198 | sgx_status_t status; 199 | 200 | status= sgx_rijndael128GCM_encrypt((sgx_aes_gcm_128bit_key_t *) key, pt, pt_len, ct, nonce, nonce_len, NULL, 0, (sgx_aes_gcm_128bit_tag_t *) tag); 201 | if ( status != SGX_SUCCESS ) { 202 | return CRYPTO_ERR_ENCRYPT; 203 | } 204 | 205 | return CRYPTO_OK; 206 | } 207 | 208 | crypto_status_t E_Crypto::aes_128_gcm_decrypt(unsigned char *key, unsigned char *nonce, unsigned long nonce_len, 209 | unsigned char *ct, unsigned long ct_len, unsigned char *pt, unsigned char *tag) 210 | { 211 | sgx_status_t status; 212 | 213 | status= sgx_rijndael128GCM_decrypt((sgx_aes_gcm_128bit_key_t *) key, ct, ct_len, pt, nonce, nonce_len, NULL, 0, (sgx_aes_gcm_128bit_tag_t *) tag); 214 | if ( status != SGX_SUCCESS ) { 215 | if ( status == SGX_ERROR_MAC_MISMATCH ) return CRYPTO_ERR_DECRYPT_AUTH; 216 | return CRYPTO_ERR_DECRYPT; 217 | } 218 | 219 | return CRYPTO_OK; 220 | } 221 | 222 | 223 | crypto_status_t E_Crypto::sha256_multi (unsigned char **messages, unsigned long *lengths, unsigned char hash[32]) 224 | { 225 | sgx_status_t status; 226 | sgx_sha_state_handle_t hsha; 227 | unsigned char **message= messages; 228 | unsigned long *length= lengths; 229 | crypto_status_t rv= CRYPTO_ERR_UNKNOWN; 230 | 231 | status= sgx_sha256_init(&hsha); 232 | if ( status != SGX_SUCCESS ) { 233 | return CRYPTO_ERR_CREATE_HASH; 234 | } 235 | 236 | while ( *message != NULL ) { 237 | status= sgx_sha256_update(*message, *length, hsha); 238 | if ( status != SGX_SUCCESS ) { 239 | rv= CRYPTO_ERR_HASH_DATA; 240 | goto cleanup; 241 | } 242 | ++message; 243 | ++length; 244 | } 245 | 246 | status= sgx_sha256_get_hash(hsha, (sgx_sha256_hash_t *) hash); 247 | if ( status != SGX_SUCCESS ) { 248 | rv= CRYPTO_ERR_FINISH_HASH; 249 | goto cleanup; 250 | } 251 | 252 | rv= CRYPTO_OK; 253 | 254 | cleanup: 255 | sgx_sha256_close(hsha); 256 | 257 | return rv; 258 | } 259 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/E_Crypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "E_DRNG.h" 4 | 5 | #define CRYPTO_KDF_ITERATIONS 50000 6 | #define CRYPTO_KDF_SALT_LEN 8 7 | 8 | #define CRYPTO_OK 0x00000000 9 | #define CRYPTO_ERR_OPEN_PROVIDER 0x10000001 10 | #define CRYPTO_ERR_CREATE_HASH 0x10000002 11 | #define CRYPTO_ERR_HASH_DATA 0x10000003 12 | #define CRYPTO_ERR_FINISH_HASH 0x10000004 13 | #define CRYPTO_ERR_SET_PROP 0x10000005 14 | #define CRYPTO_ERR_GET_PROP 0x10000006 15 | #define CRYPTO_ERR_SET_KEY 0x10000007 16 | 17 | #define CRYPTO_ERR_DECRYPT 0x10000010 18 | #define CRYPTO_ERR_DECRYPT_AUTH 0x10000011 19 | #define CRYPTO_ERR_ENCRYPT 0x10000012 20 | 21 | #define CRYPTO_ERR_PASS_MISMATCH 0x10000100 22 | #define CRYPTO_ERR_USER_CANCEL 0x10000101 23 | 24 | #define CRYPTO_ERR_DRNG 0x20000001 25 | 26 | #define CRYPTO_ERR_UNKNOWN 0xF0000001 27 | 28 | #define CRYPTO_F_IV_PROVIDED 0x00000001 29 | 30 | typedef int (*GenerateDatabaseKeyCallback)(int, int); 31 | typedef unsigned long crypto_status_t; 32 | 33 | class E_Crypto 34 | { 35 | E_DRNG drng; 36 | 37 | crypto_status_t sha256_multi (unsigned char * *messages, unsigned long *lengths, unsigned char hash[32]); 38 | 39 | crypto_status_t aes_128_gcm_encrypt(unsigned char *key, unsigned char *nonce, unsigned long nonce_len, 40 | unsigned char *pt, unsigned long pt_len, unsigned char *ct, unsigned char *tag); 41 | crypto_status_t aes_128_gcm_decrypt(unsigned char *key, unsigned char *nonce, unsigned long nonce_len, 42 | unsigned char *ct, unsigned long ct_len, unsigned char *pt, unsigned char *tag); 43 | 44 | public: 45 | E_Crypto(void); 46 | ~E_Crypto(void); 47 | 48 | crypto_status_t generate_database_key (unsigned char key_out[16], GenerateDatabaseKeyCallback callback); 49 | crypto_status_t generate_salt (unsigned char salt[8]); 50 | crypto_status_t generate_salt_ex (unsigned char * salt, unsigned long salt_len); 51 | crypto_status_t generate_nonce_gcm (unsigned char nonce[12]); 52 | 53 | crypto_status_t derive_master_key (unsigned char * passphrase, unsigned long passphrase_len, unsigned char salt[8], unsigned char key_out[16]); 54 | crypto_status_t derive_master_key_ex (unsigned char * passphrase, unsigned long passphrase_len, unsigned char * salt, unsigned long salt_len, unsigned long iterations, unsigned char key_out[16]); 55 | crypto_status_t validate_passphrase (unsigned char * passphrase, unsigned long passphrase_len, unsigned char salt[8], unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned char db_key_pt[16]); 56 | crypto_status_t validate_passphrase_ex (unsigned char * passphrase, unsigned long passphrase_len, unsigned char * salt, unsigned long salt_len, unsigned long iterations, unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned char db_key_pt[16]); 57 | 58 | crypto_status_t encrypt_database_key (unsigned char master_key[16], unsigned char db_key_pt[16], unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned int flags= 0); 59 | crypto_status_t decrypt_database_key (unsigned char master_key[16], unsigned char db_key_ct[16], unsigned char iv[12], unsigned char tag[16], unsigned char db_key_pt[16]); 60 | 61 | crypto_status_t encrypt_account_password (unsigned char db_key[16], unsigned char * password_pt, unsigned long password_len, unsigned char * password_ct, unsigned char iv[12], unsigned char tag[16], unsigned int flags= 0); 62 | crypto_status_t decrypt_account_password (unsigned char db_key[16], unsigned char * password_ct, unsigned long password_len, unsigned char iv[12], unsigned char tag[16], unsigned char * password); 63 | 64 | crypto_status_t encrypt_database (unsigned char db_key[16], unsigned char * db_serialized, unsigned long db_size, unsigned char * db_ct, unsigned char iv[12], unsigned char tag[16], unsigned int flags= 0); 65 | crypto_status_t decrypt_database (unsigned char db_key[16], unsigned char * db_ct, unsigned long db_size, unsigned char iv[12], unsigned char tag[16], unsigned char * db_serialized); 66 | }; 67 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/E_DRNG.cpp: -------------------------------------------------------------------------------- 1 | #include "E_DRNG.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define DRNG_SUPPORT_UNKNOWN -1 9 | #define DRNG_SUPPORT_NONE 0 10 | #define DRNG_SUPPORT_RDSEED 0x02 11 | 12 | typedef unsigned long ULONG; 13 | typedef uint32_t ULONG32; 14 | typedef uint64_t ULONG64; 15 | typedef unsigned long long ULONGLONG; 16 | typedef unsigned int UINT; 17 | 18 | // This is all we need since the SGX SDK takes care of RDRAND support 19 | 20 | #define HAVE_RDSEED ((_drng_support & DRNG_SUPPORT_RDSEED)==DRNG_SUPPORT_RDSEED) 21 | 22 | #ifdef __ICL 23 | #define COMPILER_HAS_RDSEED_SUPPORT 1 24 | #else 25 | # if _MSC_VER >= 1800 26 | # define COMPILER_HAS_RDSEED_SUPPORT 1 27 | # endif 28 | #endif 29 | 30 | static int _drng_support= DRNG_SUPPORT_UNKNOWN; 31 | 32 | static int _get_drng_support(int *cpuinfo); 33 | 34 | int _get_drng_support(int info[]) 35 | { 36 | int rv= DRNG_SUPPORT_NONE; 37 | 38 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 39 | __cpuidex(info, 7, 0); 40 | 41 | if ( ((UINT) info[1]) & (1<<18) ) rv|= DRNG_SUPPORT_RDSEED; 42 | #endif 43 | 44 | return rv; 45 | } 46 | 47 | E_DRNG::E_DRNG(void) 48 | { 49 | int info[4]; 50 | sgx_status_t status; 51 | 52 | if (_drng_support != DRNG_SUPPORT_UNKNOWN) return; 53 | 54 | // Check for RDSEED support 55 | 56 | status= sgx_cpuidex(info, 1, 0); 57 | if ( status == SGX_SUCCESS ) { 58 | _drng_support= _get_drng_support(info); 59 | } 60 | } 61 | 62 | E_DRNG::~E_DRNG(void) 63 | { 64 | } 65 | 66 | int E_DRNG::have_rdseed () 67 | { 68 | return HAVE_RDSEED; 69 | } 70 | 71 | int E_DRNG::random (ULONGLONG max, ULONGLONG *rand) 72 | { 73 | UINT bits; 74 | int retries= 1000; // A big enough number make failure extremely unlikely. 75 | 76 | if ( max == 0 ) { 77 | *rand= 0; 78 | return 1; 79 | } 80 | 81 | bits= ceiling_log2(max); 82 | 83 | if ( bits > 32 ) { 84 | ULONG64 val; 85 | 86 | while (retries--) { 87 | if ( ! rand64(&val) ) return 0; 88 | 89 | val>>= (64-bits); 90 | 91 | if ( val < max ) { 92 | *rand= (ULONGLONG) val; 93 | return 1; 94 | } 95 | } 96 | } else { 97 | ULONG32 val; 98 | 99 | while (retries--) { 100 | if ( ! rand32(&val) ) return 0; 101 | 102 | val>>= (32-bits); 103 | 104 | if ( val < max ) { 105 | *rand= (ULONGLONG) val; 106 | return 1; 107 | } 108 | } 109 | } 110 | 111 | // Keep the compiler from complaining. 112 | return 0; 113 | } 114 | 115 | ULONG E_DRNG::get_rand_bytes (void *buf, ULONG n) 116 | { 117 | if ( sgx_read_rand((unsigned char *) buf, n) == SGX_SUCCESS ) return n; 118 | 119 | return 0; 120 | } 121 | 122 | ULONG E_DRNG::get_seed_bytes (void *buf, ULONG n) 123 | { 124 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 125 | ULONG count= 0; 126 | BYTE seed[8]; 127 | PBYTE pb= (PBYTE) buf; 128 | ULONG blocks; 129 | 130 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, n); 131 | 132 | # ifdef _WIN64 133 | blocks= int(n/8); 134 | count= get_n_seed64((ULONG64 *) pb, blocks, 100*blocks); 135 | if ( count < blocks ) return count*8; 136 | else count*= 8; 137 | pb+= blocks*8; 138 | # else 139 | blocks= int(n/4); 140 | count= get_n_seed32((ULONG32 *) pb, blocks, 200*blocks); 141 | if ( count < blocks ) return count*4; 142 | else count*= 4; 143 | pb+= blocks*4; 144 | # endif 145 | 146 | if ( ! seed64((ULONG64 *) seed) ) return count; 147 | memcpy(pb, seed, (n-count)); 148 | 149 | return n; 150 | #else 151 | return seed_from_rdrand(buf, n); 152 | #endif 153 | } 154 | 155 | //----------------------------------------------- 156 | // RDRAND internal methods 157 | //----------------------------------------------- 158 | 159 | int E_DRNG::rand32 (ULONG32 *rand) 160 | { 161 | int retries= 10; 162 | 163 | while (retries--) if ( sgx_read_rand((unsigned char *) rand, 4) == SGX_SUCCESS ) return 1; 164 | 165 | return 0; 166 | } 167 | 168 | int E_DRNG::rand64 (ULONG64 *rand) 169 | { 170 | int retries= 10; 171 | 172 | while (retries--) if ( sgx_read_rand((unsigned char *) rand, 8) == SGX_SUCCESS ) return 1; 173 | 174 | return 0; 175 | } 176 | 177 | ULONG E_DRNG::get_n_rand32 (ULONG32 *buf, ULONG n, ULONG retries) 178 | { 179 | while (retries--) if ( sgx_read_rand((unsigned char *) buf, n*4) == SGX_SUCCESS ) return n; 180 | 181 | return 0; 182 | } 183 | 184 | ULONG E_DRNG::get_n_rand64 (ULONG64 *buf, ULONG n, ULONG retries) 185 | { 186 | while (retries--) if ( sgx_read_rand((unsigned char *) buf, n*8) == SGX_SUCCESS ) return n; 187 | 188 | return 0; 189 | } 190 | 191 | 192 | //----------------------------------------------- 193 | // RDSEED internal methods 194 | //----------------------------------------------- 195 | 196 | int E_DRNG::seed32 (ULONG32 *seed) 197 | { 198 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 199 | int retries= 100; 200 | 201 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(seed, 4); 202 | 203 | while (retries--) { 204 | if ( _rdseed32_step(seed) ) return 1; 205 | _mm_pause(); 206 | } 207 | 208 | return 0; 209 | #else 210 | return seed_from_rdrand(seed, 4); 211 | #endif 212 | } 213 | 214 | int E_DRNG::seed64 (ULONG64 *seed) 215 | { 216 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 217 | int retries= 100; 218 | 219 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(seed, 8); 220 | 221 | # ifdef _WIN64 222 | while (retries--) { 223 | if ( _rdseed64_step(seed) ) return 1; 224 | _mm_pause(); 225 | } 226 | # else 227 | if ( get_n_seed32((ULONG32 *)seed, 2, 2*retries) == 2 ) return 1; 228 | # endif 229 | 230 | return 0; 231 | #else 232 | return seed_from_rdrand(seed, 8); 233 | #endif 234 | } 235 | 236 | ULONG E_DRNG::get_n_seed32 (ULONG32 *buf, ULONG n, ULONG retries) 237 | { 238 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 239 | ULONG count= 0; 240 | 241 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, 4*n); 242 | 243 | while (n) { 244 | if ( _rdseed32_step(buf) ) { 245 | --n; 246 | ++buf; 247 | ++count; 248 | } else { 249 | if ( ! retries ) return count; 250 | retries--; 251 | } 252 | _mm_pause(); 253 | } 254 | 255 | return count; 256 | #else 257 | return seed_from_rdrand(buf, 4*n); 258 | #endif 259 | } 260 | 261 | ULONG E_DRNG::get_n_seed64 (ULONG64 *buf, ULONG n, ULONG retries) 262 | { 263 | #ifdef COMPILER_HAS_RDSEED_SUPPORT 264 | ULONG count= 0; 265 | 266 | if ( ! HAVE_RDSEED ) return seed_from_rdrand(buf, 8*n); 267 | 268 | # ifdef _WIN64 269 | while (n) { 270 | if ( _rdseed64_step(buf) ) { 271 | --n; 272 | ++buf; 273 | ++count; 274 | } else { 275 | if ( ! retries ) return count; 276 | retries--; 277 | } 278 | _mm_pause(); 279 | } 280 | 281 | return count; 282 | # else 283 | count= get_n_seed32((ULONG32 *) buf, n, retries); 284 | if ( count == n ) { 285 | count= get_n_seed32((ULONG32 *)(buf)+count, n, retries); 286 | if ( count == n ) return n; 287 | return n/2 + int(count/2); 288 | } 289 | 290 | return int(count/2); 291 | # endif 292 | #else 293 | return seed_from_rdrand(buf, 8*n); 294 | #endif 295 | } 296 | 297 | ULONG E_DRNG::seed_from_rdrand (void *buf, ULONG n) 298 | { 299 | // Use CMAC to generate 128-bit seeds from RDRAND. This is expensive 300 | // but if we don't have RDSEED this is our only option. 301 | // 302 | // The DRNG is guaranteed to reseed after 512 128-bit samples have been generated. 303 | 304 | unsigned char key[16], rand[16*512]; 305 | sgx_cmac_128bit_tag_t hash; 306 | unsigned char *bp= (unsigned char *) buf; 307 | ULONG count= 0; 308 | sgx_cmac_state_handle_t hcmac; 309 | 310 | // Create an ephemeral key 311 | 312 | if ( sgx_read_rand(key, 16) != SGX_SUCCESS ) { 313 | return 0; 314 | } 315 | 316 | // Set up CMAC 317 | 318 | if ( sgx_cmac128_init((const sgx_cmac_128bit_key_t *) key, &hcmac) != SGX_SUCCESS ) { 319 | return 0; 320 | } 321 | 322 | while (n) { 323 | ULONG chunk= ( n >= 16 ) ? 16 : n; 324 | 325 | // Fill our buffer with RDRAND values 326 | 327 | if ( sgx_read_rand(rand, 16*512) != SGX_SUCCESS ) { 328 | goto cleanup; 329 | } 330 | 331 | // Send our random values 332 | 333 | if ( sgx_cmac128_update(rand, 16*512, hcmac) != SGX_SUCCESS ) { 334 | // Error 335 | goto cleanup; 336 | } 337 | 338 | // The hash is our 128-bit seed value 339 | 340 | if ( sgx_cmac128_final(hcmac, &hash) != SGX_SUCCESS ) { 341 | // Error 342 | goto cleanup; 343 | } 344 | 345 | memcpy(bp, hash, chunk); 346 | count+= chunk; 347 | n-= chunk; 348 | bp+= chunk; 349 | } 350 | 351 | cleanup: 352 | sgx_cmac128_close(hcmac); 353 | return count; 354 | } 355 | 356 | // Fast ceiling of log base 2 357 | // http://stackoverflow.com/questions/3272424/compute-fast-log-base-2-ceiling 358 | // Question asked by: kevinlawler (http://stackoverflow.com/users/365478/kevinlawler) 359 | // Answered by: dgobbi (http://stackoverflow.com/users/2154690/dgobbi) 360 | // Licensed under http://creativecommons.org/licenses/by-sa/3.0/ 361 | // Changes to variable names only. [-JM] 362 | 363 | int E_DRNG::ceiling_log2 (ULONGLONG n) 364 | { 365 | static const ULONGLONG t[] = { 366 | 0xFFFFFFFF00000000ull, 367 | 0x00000000FFFF0000ull, 368 | 0x000000000000FF00ull, 369 | 0x00000000000000F0ull, 370 | 0x000000000000000Cull, 371 | 0x0000000000000002ull 372 | }; 373 | int i, j, k, m; 374 | 375 | j= 32; 376 | m= (((n&(n-1))==0) ? 0 : 1); 377 | 378 | for (i= 0; i< 6; ++i) { 379 | k= (((n&t[i])==0) ? 0 : j); 380 | m+= k; 381 | n>>= k; 382 | j>>= 1; 383 | } 384 | 385 | return m; 386 | } -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/E_DRNG.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class E_DRNG; 6 | typedef class E_DRNG E_DRNG; 7 | 8 | class E_DRNG 9 | { 10 | int rand32 (uint32_t *rand); 11 | int rand64 (uint64_t *rand); 12 | unsigned long get_n_rand32 (uint32_t *buf, unsigned long n, unsigned long retries); 13 | unsigned long get_n_rand64 (uint64_t *buf, unsigned long n, unsigned long retries); 14 | 15 | int seed32 (uint32_t *seed); 16 | int seed64 (uint64_t *seed); 17 | unsigned long get_n_seed32 (uint32_t *buf, unsigned long n, unsigned long retries); 18 | unsigned long get_n_seed64 (uint64_t *buf, unsigned long n, unsigned long retries); 19 | 20 | unsigned long seed_from_rdrand (void *buf, unsigned long n); 21 | 22 | int ceiling_log2 (unsigned long long n); 23 | 24 | public: 25 | E_DRNG(void); 26 | E_DRNG(int *info); 27 | ~E_DRNG(void); 28 | 29 | int have_rdseed(void); 30 | 31 | // General purpose random numbers 0 <= r < max 32 | 33 | int random (unsigned long long max, unsigned long long *rand); 34 | 35 | // Random seeds, suitable for static encryption keys and seeding 36 | // other PRNGs. 37 | 38 | unsigned long get_seed_bytes (void *buf, unsigned long n); 39 | unsigned long get_rand_bytes (void *buf, unsigned long n); 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ================================================================================================== 2 | Dynamic Link Library : passwordManagerEnclave Project Overview 3 | ================================================================================================== 4 | 5 | Enclave Project Wizard has created this passwordManagerEnclave project for you as a starting point. 6 | 7 | This file contains a summary of what you will find in each of the files that make up your project. 8 | 9 | passwordManagerEnclave.vcxproj 10 | This is the main project file for projects generated using an Enclave Wizard. 11 | It contains information about the version of the product that generated the file, and 12 | information about the platforms, configurations, and project features selected with the 13 | Enclave Wizard. 14 | 15 | passwordManagerEnclave.vcxproj.filters 16 | This is the filters file for VC++ projects generated using an Enclave Wizard. 17 | It contains information about the association between the files in your project 18 | and the filters. This association is used in the IDE to show grouping of files with 19 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 20 | "Source Files" filter). 21 | 22 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.config.xml: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | 0 4 | 0x40000 5 | 0x100000 6 | 1 7 | 1 8 | 0 9 | 0 10 | 0xFFFFFFFF 11 | 12 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.cpp: -------------------------------------------------------------------------------- 1 | #include "passwordManagerEnclave_t.h" 2 | #include "passwordManagerEnclave.h" 3 | #include "sgx_trts.h" 4 | 5 | 6 | 7 | 8 | int addUser(char *username, char *password, size_t len) 9 | { 10 | if(keypass.find(string(username)) != keypass.end() || username == NULL 11 | || password == NULL) 12 | //username is invalid, or already exists 13 | return -1; 14 | 15 | Metadata data; 16 | data.password = password; 17 | //if(!encryptPassword(&data.password)) 18 | // return -1; 19 | //keypass.insert(std::make_pair(string(username),string(password))); 20 | keypass[username] = data; 21 | size++; 22 | return 0; 23 | } 24 | 25 | int authenticate(char *username, char *password, size_t len) 26 | { 27 | string passwd = string(password); 28 | if(!encryptPassword(&passwd)) return -1; 29 | it = keypass.find(string(username)); 30 | if(it == keypass.end() || passwd.compare(it->second.password) != 0) 31 | return -1; 32 | 33 | return 0; 34 | } 35 | 36 | 37 | 38 | 39 | bool decryptPassword(string *password) 40 | { 41 | if(password == NULL) return false; 42 | //do crypto stuff 43 | return true; 44 | } 45 | 46 | 47 | bool encryptPassword(string *password) 48 | { 49 | if(password == NULL) return false; 50 | //do crypto stuff; i believe jpmechalas is handling this 51 | return true; 52 | } 53 | 54 | 55 | 56 | int findUser(char *username, size_t len) 57 | { 58 | it = keypass.find(string(username)); 59 | if(it == keypass.end()) 60 | //username does not exist 61 | return -1; 62 | return 0; 63 | } 64 | 65 | /* Skeleton code, if another parameter is added to the metadata 66 | int getXXX(char *username, size_t len) 67 | { 68 | it = keypass.find(string(username)); 69 | if(it == keypass.end()) 70 | //username does not exist 71 | return -1; 72 | 73 | Metadata data = it->second; 74 | memcpy(username,(void*)&data.XXX,data.XXX.size()+1); 75 | return 0; 76 | } 77 | */ 78 | 79 | int getAccount(char *username, size_t len) 80 | { 81 | it = keypass.find(string(username)); 82 | if(it == keypass.end()) 83 | //username does not exist 84 | return -1; 85 | 86 | Metadata data = it->second; 87 | memcpy(username,(void*)&data.account,data.account.size()+1); 88 | return 0; 89 | } 90 | 91 | 92 | /* 93 | This is for debug purposes; 94 | Takes username as input then replaces the string with password, if any) 95 | */ 96 | int getPassword(char *username, size_t len) 97 | { 98 | it = keypass.find(string(username)); 99 | if(it == keypass.end()) 100 | //username does not exist 101 | return -1; 102 | 103 | Metadata data = it->second; 104 | 105 | //string password(MAX_BUF_LEN,'\0'); 106 | //memcpy((void*)&password,it->second.c_str(),strlen(it->second.c_str())+1); 107 | //if(!decryptPassword(&data.password)) 108 | // return -1; 109 | memcpy(username,(void*)&data.password,data.password.size()+1); 110 | return 0; 111 | } 112 | 113 | int getSize() 114 | { 115 | return size; 116 | } 117 | 118 | int getUrl(char *username, size_t len) 119 | { 120 | it = keypass.find(string(username)); 121 | if(it == keypass.end()) 122 | //username does not exist 123 | return -1; 124 | 125 | Metadata data = it->second; 126 | memcpy(username,(void*)&data.url,data.url.size()+1); 127 | return 0; 128 | } 129 | 130 | 131 | 132 | 133 | int removeUser(char *username, size_t len) 134 | { 135 | //if(!authenticate(username,password)) 136 | // return -1; 137 | if(keypass.erase(username) != 1) 138 | return -1; 139 | size--; 140 | return 0; 141 | } 142 | 143 | 144 | 145 | /* 146 | int setXXX(char *username, char *newVal, size_t len) 147 | { 148 | it = keypass.find(string(username)); 149 | Metadata data = it->second; 150 | data.XXX = newVal; 151 | it->second = data; 152 | 153 | return 0; 154 | } 155 | */ 156 | 157 | int setAccount(char *username, char *newVal, size_t len) 158 | { 159 | it = keypass.find(string(username)); 160 | Metadata data = it->second; 161 | data.account = newVal; 162 | it->second = data; 163 | 164 | return 0; 165 | } 166 | 167 | 168 | int setPassword(char *username, char *newVal, size_t len) 169 | { 170 | /* 171 | if(it == keypass.end()) 172 | //username does not exist 173 | return -1; 174 | if(!authenticate(username,oldPasswd)) 175 | return -1; 176 | */ 177 | 178 | it = keypass.find(string(username)); 179 | Metadata data = it->second; 180 | data.password = newVal; 181 | it->second = data; 182 | //memcpy((void*)(it->second.c_str()),password,strlen(password)+1); 183 | 184 | return 0; 185 | } 186 | 187 | int setUrl(char *username, char *newVal, size_t len) 188 | { 189 | it = keypass.find(string(username)); 190 | Metadata data = it->second; 191 | data.url = newVal; 192 | it->second = data; 193 | 194 | return 0; 195 | } -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.edl: -------------------------------------------------------------------------------- 1 | enclave { 2 | 3 | /* Needed for the sgx_cpuidex */ 4 | from "sgx_tstdc.edl" import *; 5 | 6 | trusted { 7 | /* define ECALLs here. */ 8 | public int addUser([in, string] char *username, [in, string] char *password, size_t len); 9 | public int authenticate([in, string] char *username, [in, string] char *password, size_t len); 10 | public int findUser([in, string] char* username, size_t len); 11 | public int getAccount([in, out, string] char *username, size_t len); 12 | public int getPassword([in, out, string] char *username, size_t len); 13 | public int getUrl([in, out, string] char *username, size_t len); 14 | public int removeUser([in, string] char *username, size_t len); 15 | 16 | //NOTE: since the code is written under the assumption that there will be a GUI 17 | // wrapper, setter functions assume user is authenticated 18 | 19 | public int setAccount([in, string] char *username, [in, string] char *data, size_t len); 20 | public int setPassword([in, string] char *username, [in, string] char *data, size_t len); 21 | public int setUrl([in, string] char *username, [in, string] char *data, size_t len); 22 | 23 | }; 24 | 25 | untrusted { 26 | /* define OCALLs here. */ 27 | int getSize(); 28 | 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | #define MAX_BUF_LEN 100 7 | typedef struct{ 8 | string password; 9 | string url; 10 | string account; 11 | //int token; //user is authorized to see/edit data 12 | //add more if necessary 13 | } Metadata; 14 | 15 | 16 | std::map keypass; //matches username with account info 17 | std::map::iterator it;//_metadata; 18 | int size = 0; 19 | 20 | int addUser(char*, char*, size_t); //ECALL 21 | int authenticate(char*,char*,size_t); 22 | bool decryptPassword(string*); 23 | bool encryptPassword(string*); 24 | int findUser(char*,size_t); 25 | 26 | int getAccount(char*, size_t); //ECALL 27 | int getPassword(char*, size_t); //ECALL, debug 28 | int getSize(); //OCALL 29 | int getUrl(char*, size_t); //ECALL 30 | int removeUser(char*, size_t); //ECAL 31 | //NOTE: since the code is written under the assumption that there will be a GUI 32 | // wrapper, setter functions assume user is authenticated 33 | int setAccount(char*, char*, size_t); //ECALL 34 | int setPassword(char*, char*, size_t); //ECALL 35 | int setUrl(char*, char*, size_t); //ECALL 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Prerelease 10 | Win32 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Simulation 18 | Win32 19 | 20 | 21 | 22 | {A38886EA-0D2E-492E-B8DA-A02A9E0EC7E8} 23 | v4.6.1 24 | 25 | 26 | 27 | DynamicLibrary 28 | v110 29 | 30 | 31 | DynamicLibrary 32 | v110 33 | 34 | 35 | DynamicLibrary 36 | v110 37 | 38 | 39 | DynamicLibrary 40 | v110 41 | 42 | 43 | DynamicLibrary 44 | v110 45 | 46 | 47 | DynamicLibrary 48 | v110 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | false 74 | false 75 | $(NoInherit) 76 | $(NoInherit) 77 | 78 | 79 | false 80 | false 81 | $(NoInherit) 82 | $(NoInherit) 83 | 84 | 85 | false 86 | false 87 | $(NoInherit) 88 | $(NoInherit) 89 | 90 | 91 | false 92 | false 93 | $(NoInherit) 94 | $(NoInherit) 95 | 96 | 97 | 98 | Default 99 | MultiThreadedDebug 100 | Disabled 101 | Level3 102 | $(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\stlport;%(AdditionalIncludeDirectories) 103 | 104 | 105 | sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcrypto_opt.lib;sgx_tstdcxx.lib 106 | $(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) 107 | true 108 | 109 | true 110 | true 111 | 112 | 113 | "$(SGXSDKInstallPath)bin\win32\release\sgx_sign.exe" sign -key "$(ProjectDir)passwordManagerEnclave_private.pem" -enclave "$(OutDir)passwordManagerEnclave.dll" -out "$(OutDir)passwordManagerEnclave.signed.dll" -config "$(ProjectDir)passwordManagerEnclave.config.xml" 114 | sign the enclave 115 | 116 | 117 | 118 | 119 | Default 120 | MultiThreadedDebug 121 | Disabled 122 | Level3 123 | $(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\stlport;%(AdditionalIncludeDirectories) 124 | 125 | 126 | sgx_trts_sim.lib;sgx_tstdc.lib;sgx_tservice_sim.lib;sgx_tcrypto.lib;sgx_tstdcxx.lib 127 | $(SGXSDKInstallPath)bin\$(Platform)\Debug 128 | true 129 | 130 | 131 | true 132 | true 133 | 134 | 135 | "$(SGXSDKInstallPath)bin\win32\release\sgx_sign.exe" sign -key "$(ProjectDir)passwordManagerEnclave_private.pem" -enclave "$(OutDir)passwordManagerEnclave.dll" -out "$(OutDir)passwordManagerEnclave.signed.dll" -config "$(ProjectDir)passwordManagerEnclave.config.xml" 136 | sign the enclave 137 | 138 | 139 | 140 | 141 | Default 142 | MultiThreaded 143 | MaxSpeed 144 | Level3 145 | $(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\stlport;%(AdditionalIncludeDirectories) 146 | true 147 | 148 | 149 | sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcrypto_opt.lib;sgx_tstdcxx.lib 150 | $(SGXSDKInstallPath)bin\$(Platform)\$(Configuration) 151 | true 152 | 153 | true 154 | true 155 | true 156 | 157 | 158 | "$(SGXSDKInstallPath)bin\win32\release\sgx_sign.exe" gendata -enclave "$(OutDir)passwordManagerEnclave.dll" -out "$(OutDir)passwordManagerEnclave.hex" -config "$(ProjectDir)passwordManagerEnclave.config.xml" 159 | generate the enclave signing material 160 | 161 | 162 | 163 | 164 | Default 165 | MultiThreaded 166 | MaxSpeed 167 | Level3 168 | $(SGXSDKInstallPath)include;$(SGXSDKInstallPath)include\tlibc;$(SGXSDKInstallPath)include\stlport;%(AdditionalIncludeDirectories) 169 | true 170 | 171 | 172 | sgx_trts.lib;sgx_tstdc.lib;sgx_tservice.lib;sgx_tcrypto_opt.lib;sgx_tstdcxx.lib 173 | $(SGXSDKInstallPath)bin\$(Platform)\Release 174 | true 175 | 176 | 177 | true 178 | true 179 | true 180 | 181 | 182 | "$(SGXSDKInstallPath)bin\win32\release\sgx_sign.exe" sign -key "$(ProjectDir)passwordManagerEnclave_private.pem" -enclave "$(OutDir)passwordManagerEnclave.dll" -out "$(OutDir)passwordManagerEnclave.signed.dll" -config "$(ProjectDir)passwordManagerEnclave.config.xml" 183 | sign the enclave 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "$(ProjectDir)passwordManagerEnclave.edl" --search-path "$(SGXSDKInstallPath)include" 201 | Creating proxy/bridge routines 202 | $(ProjectName)_t.h;$(ProjectName)_t.c;%(Outputs) 203 | passwordManagerEnclave.config.xml;%(AdditionalInputs) 204 | "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "$(ProjectDir)passwordManagerEnclave.edl" --search-path "$(SGXSDKInstallPath)include" 205 | Creating proxy/bridge routines 206 | $(ProjectName)_t.h;$(ProjectName)_t.c;%(Outputs) 207 | passwordManagerEnclave.config.xml;%(AdditionalInputs) 208 | "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "$(ProjectDir)passwordManagerEnclave.edl" --search-path "$(SGXSDKInstallPath)include" 209 | Creating proxy/bridge routines 210 | $(ProjectName)_t.h;$(ProjectName)_t.c;%(Outputs) 211 | passwordManagerEnclave.config.xml;%(AdditionalInputs) 212 | "$(SGXSDKInstallPath)bin\win32\release\sgx_edger8r.exe" --trusted "$(ProjectDir)passwordManagerEnclave.edl" --search-path "$(SGXSDKInstallPath)include" 213 | Creating proxy/bridge routines 214 | $(ProjectName)_t.h;$(ProjectName)_t.c;%(Outputs) 215 | passwordManagerEnclave.config.xml;%(AdditionalInputs) 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {a57f6e45-dd66-435c-b747-2413924d472e} 6 | 7 | 8 | {5d357a2c-ea04-4805-8edd-bbd95cf9da2e} 9 | cpp;c;edl;def; .. and other options 10 | 11 | 12 | {320f3c30-3bce-4e6f-89b2-47493ef8267e} 13 | h;hpp; .. and other options 14 | 15 | 16 | {aa920040-ac26-415c-b3b0-2249a91f0008} 17 | rc;xml;pem; .. and other options 18 | 19 | 20 | 21 | 22 | Generated Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Generated Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | 49 | 50 | Resource Files 51 | 52 | 53 | 54 | 55 | Resource Files 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Source Files 64 | 65 | 66 | -------------------------------------------------------------------------------- /passwordManager/passwordManagerEnclave/passwordManagerEnclave/passwordManagerEnclave_private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4wIBAAKCAYEAzdkJXRn0Wseu7kYBxNN77OwqHiBPFl3ZeOn0OLH6Osm+bO9i 3 | J8H2m8DcwFYR/LtzwZJ3AtwcAeH7tPsvWL3LtlAT+p5Wq5ouy90byalXW2e8Bm9b 4 | bxEQyUIR8ZH4B1Mo1B904n6xsKVdI+S40xV/g+ZczJE1w6yFQJIbD3SfXDeFpe0j 5 | Pg4OcS/7nLZvsWrUFGcg8D+vm3jgFfGnzriwxnX2DxCjQAqZiHdNUeHBV9SHfGaJ 6 | 4jyXQ0BjaL4sJpfD5UhKAfjfH3lsX1Y7taEYW76Wl9CwZ/QiRQykwpuwaaHxwOD2 7 | W8wizgtq2+yLLeZRNUIgQd+DE9t2UKNDSDoRXa0mqvH3PGGu6+VAXS1vBWG4P1+S 8 | O+wXrSjVlETIhyBXakUVxguohDe3jzUCjc6iJ49fgdLbLFnbb+Hb19HQtl0uNXC+ 9 | Xzzs+cU6iGZS6Z9cB0Ii/kJrdUzg54a2yOXwTTtJ/gddIWiXShFyjuROS4ShaS6T 10 | da8VMERJyg0CxYbTAgEDAoIBgQCJO1uTZqLnL8n0LqvYjP1InXFpat9kPpD7RqLQ 11 | dqbR29RIn5bFK/m9Kz3VjraofPfWYaSskr1WlqfN/Mo7KTJ5irf8aY8dEXSH6L0x 12 | G4+SRSgESjz0tgsw1rahC/qvjMXiv6NBqcvLGOjCmHs3Y6pX7uiIYM6CcwOAYWdf 13 | oxToJQPD82zUCV72H/0TJEp2RzgNmhX1f8pnpeq5S8U0eyCETqQKCxeABxEFpN42 14 | loDlOFpS7waW0w+CKuzwfsgZuoFlCyA6jufaxRTOio8loI18oX8pJLQEKf0AWpJ3 15 | u8hPVCiF8xXQYhac6AUV1uMvCOOgGL9nuApoTt9B4hWYVNIkBSIyquAn0/rhlRJo 16 | +leyaCXEeaNf5dMsryuqhuT/oQ2H8vA0TqZ1Gq94hZMKLPiZQYr6O17z/z1Bwbpf 17 | oR8jwy1mldz3bIWX7JFsF6A5NTignhuYYGGAIp8QSTXAl9As/CZUseVUcTWONrBs 18 | jt4raHl2VKYj6xAzIuGRCLYlujsCgcEA/1N0wVop1Vy72epd+6J+h9IilYjKgcKl 19 | ksGvu0eSPkTTa69k/czcrt2GyYEO6pqwBZOvmlRqvBs/+lxVpOww7ALFK36M3MC4 20 | PdK13EnvEkn9Z/ObjxhbPKBAQxdLet9i0QYnIdxUvFjcavGWm1NhJtNP4I/Luo3e 21 | HqLxT64HhmPfiz/fecuCaT0rHqmWzLFTt16Irv6ErDEWlFOG7ibJei6fji8AtnL9 22 | q+QDizdieyabxqphiLlKijJxWODc8jS3AoHBAM5kJOjIWYH1EU+cBwGNxZj6NUSQ 23 | 19/ygTHDGVO6cbRe4YxE8KVsJDPR3HGpJ3y+S7+JUYv3CLtJ53NzzT7OpTuirjNz 24 | GiPi/luy7uNr/Gd7gjC1gZz6/62B09FjJYzPYE1ShlW5Whg20+97D2M3zBrZvynq 25 | AQPNIW6cUviyGnpUipBQE3JOoiylNUeZS8ceM172cOqzVIjn27rFXznbbo+ScPDN 26 | hGxLyUjbZmDWno9BT3EFOLcVMlldhhefFJq6xQKBwQCqN6MrkXE46H078ZP9Fv8F 27 | NsG5BdxWgcO3K8p82mF+2IzydO3+iJMfPlnbq19HEcquYnURjZx9Z3/8PY5t8stI 28 | AdjHqbM91dApNyPoMUoMMVOaome0uud9wCrXZNz8lOyLWW9r6Dh9kJLx9mRnjOtv 29 | N4qVtTJ8XpQUbKDfyVpZl+pc1T+mh6xGKMdpxmSIdjfPlFsfVFhyy2Ri4ln0Gdum 30 | yb+0H1XO91PH7VeyJOxSGb0vHEEF0NxcIaDl6z32zc8CgcEAiZgYmzA7q/i2NRKv 31 | Vl6Du1F42GCP6qGrdoIQ4nxLzZSWXYNLGPLCzTaS9nDE/dQyf7DhB/oF0jFE96KI 32 | 1InDfRcezPdmwpdUPSH0l51S76esIHkBE1H/yQE34OzDszTq3jcEOSY8ECSNSlIK 33 | QiUyvJEqG/FWAojA9Gg3UHa8UY2xtYq3oYnBcxjOL7uH2hQiP0718czjBe/n0djq 34 | JpJJtQxLSzOtnYfbheeZleRptNY09gN7JLjMO5OuumoNvHyDAoHASrGPao1FKVXk 35 | chaZB1/HucL2TM2N6UUBgArAvZy9poaFhCdfS2mjlGe7SKf1Wvqlj4e8p4AS9jma 36 | h8G4DkEQYmUA2+TyDBYSZOOAu67KWSxog5lX7/McLqEERPUZp+AsRVGAaqaiRbaT 37 | XI8iLsn62tQspFtQYiDbo2FEOdJfdhjmnlkbf1WVyPuGkLhn/4tK1wRR1S/RSJ1/ 38 | cpOGtVvZtYUcvzEtJ9niYPHXFCVG7d8FcCqkru5CHKewqOdCh+U2 39 | -----END RSA PRIVATE KEY----- 40 | --------------------------------------------------------------------------------