📄 util-linux-2.12r.diff
字号:
+ }+ sha512_final(&s);++ /*+ * Overwrite 40 KB of old fs data 20 times so that recovering+ * SHA-512 output beyond this point is difficult and expensive.+ */+ for(y = 0; y < 20; y++) {+ int z;+ struct {+ struct timeval tv;+ unsigned char h[64];+ int x,y,z;+ } j;+ if(xx_lseek(fd, offset, SEEK_SET) == -1) break;+ memcpy(&j.h[0], &s.sha_out[0], 64);+ gettimeofday(&j.tv, NULL);+ j.y = y;+ for(x = 1; x <= 10; x++) {+ j.x = x;+ for(z = 0; z < sizeof(b); z += 64) {+ j.z = z;+ sha512_hash_buffer((unsigned char *)&j, sizeof(j), &b[z], 64);+ }+ if((sizelimit > 0) && ((sizeof(b) * x) > sizelimit)) break;+ if(rd_wr_retry(fd, &b[0], sizeof(b), 1) != sizeof(b)) break;+ }+ memset(&j, 0, sizeof(j));+ if(fsync(fd)) break;+ }+ close(fd);++ /*+ * Use all 512 bits of hash output+ */+ memcpy(&b[0], &s.sha_out[0], 64);+ memset(&s, 0, sizeof(s));++ /*+ * Read 32 bytes of random entropy from kernel's random+ * number generator. This code may be executed early on startup+ * scripts and amount of random entropy may be non-existent.+ * SHA-512 of old fs data is used as workaround for missing+ * entropy in kernel's random number generator.+ */+ if((fd = open("/dev/urandom", O_RDONLY)) == -1) {+ fprintf(stderr, _("Error: unable to open /dev/urandom\n"));+ return 1;+ }+ rd_wr_retry(fd, &b[64], 32, 0);++ /* generate multi-key hashes */+ x = 0;+ while(x < 65) {+ rd_wr_retry(fd, &b[64+32], 16, 0);+ sha512_hash_buffer(&b[0], 64+32+16, k, 32);+ k += 32;+ x++;+ }++ close(fd);+ memset(&b[0], 0, sizeof(b));+ return 0; } +#if !defined(MAIN)+static int loop_fork_mkfs_command(char *device, char *fstype)+{+ int x, y = 0;+ char *a[10], *e[1];++ sync();+ if(!(x = fork())) {+ if((x = open("/dev/null", O_WRONLY)) >= 0) {+ dup2(x, 0);+ dup2(x, 1);+ dup2(x, 2);+ close(x);+ }+ x = 0;+ a[x++] = "mkfs";+ a[x++] = "-t";+ a[x++] = fstype;+ /* mkfs.reiserfs and mkfs.xfs need -f option */+ if(!strcmp(fstype, "reiserfs") || !strcmp(fstype, "xfs")) {+ a[x++] = "-f";+ }+ a[x++] = device;+ a[x] = 0;+ e[0] = 0;+ if(setgid(getgid())) exit(1);+ if(setuid(getuid())) exit(1);+ for(x = 3; x < 1024; x++) {+ close(x);+ }+ execve("/sbin/mkfs", &a[0], &e[0]);+ exit(1);+ }+ if(x == -1) {+ fprintf(stderr, _("Error: fork failed\n"));+ return 1;+ }+ waitpid(x, &y, 0);+ sync();+ if(!WIFEXITED(y) || (WEXITSTATUS(y) != 0)) {+ fprintf(stderr, _("Error: encrypted file system mkfs failed\n"));+ return 1;+ }+ return 0;+}+#endif+ int-set_loop(const char *device, const char *file, unsigned long long offset,- const char *encryption, int pfd, int *loopro) {- struct loop_info64 loopinfo64;- int fd, ffd, mode, i;- char *pass;+set_loop(const char *device, const char *file, int *loopro, const char **fstype, unsigned int *AutoChmodPtr, int busyRetVal) {+ struct loop_info64 loopinfo;+ int fd, ffd, mode, i, errRetVal = 1;+ char *pass, *apiName = NULL;+ void (*hashFunc)(unsigned char *, int, unsigned char *, int);+ unsigned char multiKeyBits[65][32];+ int minPassLen = LOOP_PASSWORD_MIN_LENGTH;+ int run_mkfs_command = 0; + loopFileName = (char *)file;+ multiKeyMode = 0; mode = (*loopro ? O_RDONLY : O_RDWR); if ((ffd = open(file, mode)) < 0) { if (!*loopro && errno == EROFS)@@ -256,159 +827,253 @@ } if ((fd = open(device, mode)) < 0) { perror (device);- return 1;+ goto close_ffd_return1; } *loopro = (mode == O_RDONLY); - memset(&loopinfo64, 0, sizeof(loopinfo64));-- xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);-- if (encryption && *encryption) {- if (digits_only(encryption)) {- loopinfo64.lo_encrypt_type = atoi(encryption);- } else {- loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;- snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,- "%s", encryption);- }+ if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {+ if(errno == EBUSY)+ errRetVal = busyRetVal;+ if((errRetVal != 2) || verbose)+ perror("ioctl: LOOP_SET_FD");+keyclean_close_fd_ffd_return1:+ memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));+ memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits));+ close (fd);+close_ffd_return1:+ close (ffd);+ return errRetVal; } - loopinfo64.lo_offset = offset;+ memset (&loopinfo, 0, sizeof (loopinfo));+ xstrncpy ((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);+ if (loopEncryptionType)+ loopinfo.lo_encrypt_type = loop_crypt_type (loopEncryptionType, &loopinfo.lo_encrypt_key_size, &apiName);+ if (loopOffsetBytes)+ loopinfo.lo_offset = mystrtoull(loopOffsetBytes, 1);+ if (loopSizeBytes)+ loopinfo.lo_sizelimit = mystrtoull(loopSizeBytes, 0); -#ifdef MCL_FUTURE +#ifdef MCL_FUTURE /* * Oh-oh, sensitive data coming up. Better lock into memory to prevent * passwd etc being swapped out and left somewhere on disk. */- - if(mlockall(MCL_CURRENT | MCL_FUTURE)) {++ if(loopinfo.lo_encrypt_type && mlockall(MCL_CURRENT | MCL_FUTURE)) { perror("memlock");+ ioctl (fd, LOOP_CLR_FD, 0); fprintf(stderr, _("Couldn't lock into memory, exiting.\n")); exit(1); } #endif - switch (loopinfo64.lo_encrypt_type) {+ switch (loopinfo.lo_encrypt_type) { case LO_CRYPT_NONE:- loopinfo64.lo_encrypt_key_size = 0;+ loopinfo.lo_encrypt_key_size = 0; break; case LO_CRYPT_XOR:- pass = getpass(_("Password: "));- goto gotpass;+ pass = sGetPass (1, 0);+ if(!pass) goto loop_clr_fd_out;+ xstrncpy ((char *)loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);+ loopinfo.lo_encrypt_key_size = strlen((char*)loopinfo.lo_encrypt_key);+ break;+ case 3: /* LO_CRYPT_FISH2 */+ case 4: /* LO_CRYPT_BLOW */+ case 7: /* LO_CRYPT_SERPENT */+ case 8: /* LO_CRYPT_MARS */+ case 11: /* LO_CRYPT_RC6 */+ case 12: /* LO_CRYPT_DES_EDE3 */+ case 16: /* LO_CRYPT_AES */+ case 18: /* LO_CRYPT_CRYPTOAPI */+ /* set default hash function */+ hashFunc = sha256_hash_buffer;+ if(loopinfo.lo_encrypt_key_size == 24) hashFunc = sha384_hash_buffer;+ if(loopinfo.lo_encrypt_key_size == 32) hashFunc = sha512_hash_buffer;+ /* possibly override default hash function */+ if(passHashFuncName) {+ if(!strcasecmp(passHashFuncName, "sha256")) {+ hashFunc = sha256_hash_buffer;+ } else if(!strcasecmp(passHashFuncName, "sha384")) {+ hashFunc = sha384_hash_buffer;+ } else if(!strcasecmp(passHashFuncName, "sha512")) {+ hashFunc = sha512_hash_buffer;+ } else if(!strcasecmp(passHashFuncName, "rmd160")) {+ hashFunc = rmd160HashTwiceWithA;+ minPassLen = 1;+ } else if(!strcasecmp(passHashFuncName, "unhashed1")) {+ hashFunc = unhashed1_key_setup;+ } else if(!strcasecmp(passHashFuncName, "unhashed2")) {+ hashFunc = unhashed2_key_setup;+ minPassLen = 1;+ } else if(!strcasecmp(passHashFuncName, "unhashed3") && passFDnumber && !gpgKeyFile) {+ /* unhashed3 hash type reads binary key from file descriptor. */+ /* This is not compatible with gpgkey= mount option */+ if(rd_wr_retry(atoi(passFDnumber), (char *)&loopinfo.lo_encrypt_key[0], LO_KEY_SIZE, 0) < 1) {+ fprintf(stderr, _("Error: couldn't read binary key\n"));+ goto loop_clr_fd_out;+ }+ break; /* out of switch(loopinfo.lo_encrypt_type) */+ } else if(!strncasecmp(passHashFuncName, "random", 6) && ((passHashFuncName[6] == 0) || (passHashFuncName[6] == '/'))) {+ /* random hash type sets up 65 random keys */+ /* WARNING! DO NOT USE RANDOM HASH TYPE ON PARTITION WITH EXISTING */+ /* IMPORTANT DATA ON IT. RANDOM HASH TYPE WILL DESTROY YOUR DATA. */+ if(loop_create_random_keys((char*)file, loopinfo.lo_offset, loopinfo.lo_sizelimit, *loopro, &multiKeyBits[0][0])) {+ goto loop_clr_fd_out;+ }+ memcpy(&loopinfo.lo_encrypt_key[0], &multiKeyBits[0][0], sizeof(loopinfo.lo_encrypt_key));+ run_mkfs_command = multiKeyMode = 1000;+ break; /* out of switch(loopinfo.lo_encrypt_type) */+ }+ }+ pass = sGetPass (minPassLen, LOOP_PASSWORD_MIN_LENGTH);+ if(!pass) goto loop_clr_fd_out;+ i = strlen(pass);+ if(hashFunc == unhashed1_key_setup) {+ /* this is for compatibility with historic loop-AES version */+ loopinfo.lo_encrypt_key_size = 16; /* 128 bits */+ if(i >= 32) loopinfo.lo_encrypt_key_size = 24; /* 192 bits */+ if(i >= 43) loopinfo.lo_encrypt_key_size = 32; /* 256 bits */+ }+ (*hashFunc)((unsigned char *)pass, i, &loopinfo.lo_encrypt_key[0], sizeof(loopinfo.lo_encrypt_key));+ if(multiKeyMode) {+ int r = 0, t;+ while(r < multiKeyMode) {+ t = strlen(multiKeyPass[r]);+ (*hashFunc)((unsigned char *)multiKeyPass[r], t, &multiKeyBits[r][0], 32);+ memset(multiKeyPass[r], 0, t);+ /*+ * MultiKeyMode uses md5 IV. One key mode uses sector IV. Sector IV+ * and md5 IV v2 and v3 are all computed differently. This first key+ * byte XOR with 0x55/0xF4 is needed to cause complete decrypt failure+ * in cases where data is encrypted with one type of IV and decrypted+ * with another type IV. If identical key was used but only IV was+ * computed differently, only first plaintext block of 512 byte CBC+ * chain would decrypt incorrectly and rest would decrypt correctly.+ * Partially correct decryption is dangerous. Decrypting all blocks+ * incorrectly is safer because file system mount will simply fail.+ */+ if(multiKeyMode == 65) {+ multiKeyBits[r][0] ^= 0xF4; /* version 3 */+ } else {+ multiKeyBits[r][0] ^= 0x55; /* version 2 */+ }+ r++;+ }+ } else if(passIterThousands) {+ aes_context ctx;+ unsigned long iter = 0;+ unsigned char tempkey[32];+ /*+ * Set up AES-256 encryption key using same password and hash function+ * as before but with password bit 0 flipped before hashing. That key+ * is then used to encrypt actual loop key 'itercountk' thousand times.+ */+ pass[0] ^= 1;+ (*hashFunc)((unsigned char *)pass, i, &tempkey[0], 32);+ aes_set_key(&ctx, &tempkey[0], 32, 0);+ sscanf(passIterThousands, "%lu", &iter);+ iter *= 1000;+ while(iter > 0) {+ /* encrypt both 128bit blocks with AES-256 */+ aes_encrypt(&ctx, &loopinfo.lo_encrypt_key[ 0], &loopinfo.lo_encrypt_key[ 0]);+ aes_encrypt(&ctx, &loopinfo.lo_encrypt_key[16], &loopinfo.lo_encrypt_key[16]);+ /* exchange upper half of first block with lower half of second block */+ memcpy(&tempkey[0], &loopinfo.lo_encrypt_key[8], 8);+ memcpy(&loopinfo.lo_encrypt_key[8], &loopinfo.lo_encrypt_key[16], 8);+ memcpy(&loopinfo.lo_encrypt_key[16], &tempkey[0], 8);+ iter--;+ }+ memset(&ctx, 0, sizeof(ctx));+ memset(&tempkey[0], 0, sizeof(tempkey));+ }+ memset(pass, 0, i); /* erase original password */+ break; default:- pass = xgetpass(pfd, _("Password: "));- gotpass:- memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);- xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);- memset(pass, 0, strlen(pass));- loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;+ fprintf (stderr, _("Error: don't know how to get key for encryption system %d\n"), loopinfo.lo_encrypt_type);+ goto loop_clr_fd_out; } - if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {- perror("ioctl: LOOP_SET_FD");- return 1;+ if(loInitValue) {+ /* cipher modules are free to do whatever they want with this value */+ i = 0;+ sscanf(loInitValue, "%d", &i);+ loopinfo.lo_init[0] = i; }- close (ffd); - i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);- if (i) {- struct loop_info loopinfo;- int errsv = errno;-- i = loop_info64_to_old(&loopinfo64, &loopinfo);- if (i) {- errno = errsv;- perror("ioctl: LOOP_SET_STATUS64");- } else {- i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);- if (i)- perror("ioctl: LOOP_SET_STATUS");+ /* type 18 == LO_CRYPT_CRYPTOAPI */+ if ((loopinfo.lo_encrypt_type == 18) || (loop_set_status64_ioctl(fd, &loopinfo) < 0)) {+ /* direct cipher interface failed - try CryptoAPI interface now */+ if(!apiName || (try_cryptoapi_loop_interface(fd, &loopinfo, apiName) < 0)) {+ fprintf(stderr, _("ioctl: LOOP_SET_STATUS: %s, requested cipher or key length (%d bits) not supported by kernel\n"), strerror(errno), loopinfo.lo_encrypt_key_size << 3);+ loop_clr_fd_out:+ (void) ioctl (fd, LOOP_CLR_FD, 0);+ goto keyclean_close_fd_ffd_return1; }- memset(&loopinfo, 0, sizeof(loopinfo)); }- memset(&loopinfo64, 0, sizeof(loopinfo64));-- if (i) {- ioctl (fd, LOOP_CLR_FD, 0);- close (fd);- return 1;+ if(multiKeyMode >= 65) {+ if(ioctl(fd, LOOP_MULTI_KEY_SETUP_V3, &multiKeyBits[0][0]) < 0) {+ if(multiKeyMode == 1000) goto try_v2_setup;+ perror("ioctl: LOOP_MULTI_KEY_SETUP_V3");+ goto loop_clr_fd_out;+ }+ } else if(multiKeyMode == 64) {+ try_v2_setup:+ if((ioctl(fd, LOOP_MULTI_KEY_SETUP, &multiKeyBits[0][0]) < 0) && (multiKeyMode != 1000)) {+ perror("ioctl: LOOP_MULTI_KEY_SETUP");+ goto loop_clr_fd_out;+ } }- close (fd);-- if (verbose > 1)- printf(_("set_loop(%s,%s,%llu): success\n"),- device, file, offset);- return 0;-}--int -del_loop (const char *device) {- int fd; - if ((fd = open (device, O_RDONLY)) < 0) {- int errsv = errno;- fprintf(stderr, _("loop: can't delete device %s: %s\n"),- device, strerror (errsv));- return 1;- }- if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {- perror ("ioctl: LOOP_CLR_FD");- return 1;- }+ memset(loopinfo.lo_encrypt_key, 0, sizeof(loopinfo.lo_encrypt_key));+ memset(&multiKeyBits[0][0], 0, sizeof(multiKeyBits)); close (fd);- if (verbose > 1)- printf(_("del_loop(%s): success\n"), device);- return 0;-}--#else /* no LOOP_SET_FD defined */-static void-mutter(void) {- fprintf(stderr,- _("This mount was compiled without loop support. "- "Please recompile.\n"));-} --int-set_loop (const char *device, const char *file, unsigned long long offset,- const char *encryption, int *loopro) {- mutter();- return 1;-}+ close (ffd); -int-del_loop (const char *device) {- mutter();- return 1;-}+#if !defined(MAIN)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -