/* * Set the key using an ioctl for rt-privacy NFSv4 mounts. * * Copyright (C) 2007 Avishay Traeger, Kumar Thangavelu, Erez Zadok * Copyright (C) 2007 Stony Brook University (SUNY) * */ #include #include #include #include #include #include #include #include #include #include #include #include /* Copied from the custom header file nfs4_crypt.h */ struct _nfs4_ioctl_SETKEY { char ukey [16]; }; #define NFS4_IOCTL_SETKEY _IOW(0x15, 10, struct _nfs4_ioctl_SETKEY) /* End Copied from nfs4_crypt.h */ int print_hex(unsigned char *buf, int len) { int i; int n; for(i=0,n=0;i 7){ printf("\n"); n = 0; } printf("0x%02x, ",buf[i]); n++; } printf("\n"); return(0); } int calculate_salt(char *passwd, int passwd_len, char *salt, int salt_len) { EVP_MD_CTX mdctx; unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len; OpenSSL_add_all_digests(); EVP_MD_CTX_init(&mdctx); EVP_DigestInit_ex(&mdctx, EVP_sha1(), NULL); EVP_DigestUpdate(&mdctx, passwd, passwd_len); EVP_DigestFinal_ex(&mdctx, md_value, &md_len); EVP_MD_CTX_cleanup(&mdctx); memset(salt, 0, salt_len); if (md_len > salt_len) md_len = salt_len; memcpy(salt, md_value, md_len); return 0; } #define MAX_PASSWORD 64 #define MAX_KEY 16 int main(int argc, char *argv[]) { int fd, ret=0; struct _nfs4_ioctl_SETKEY val; char password[MAX_PASSWORD]; char salt[PKCS5_SALT_LEN]; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s file [passphrase]\n", argv[0]); exit(1); } fd = open(argv[1], O_RDONLY); if (fd < 0) { perror(argv[1]); exit(1); } memset(password, 0, MAX_PASSWORD); if (argc != 3) { printf("Enter key: "); fgets(password, sizeof(password), stdin); /* Remove the newline */ password[strlen(password)-1] = 0; } else { /* We cannot use the last 2 chars as then it will not be * compatible with fgets impl */ strncpy(password, argv[2], sizeof(password)-2); } if(calculate_salt(password, MAX_PASSWORD, salt, PKCS5_SALT_LEN)) { printf("ERROR: Unable to initialize salt. Please check if you have openssl libraries\n"); exit(-1); } memset(val.ukey, 0, sizeof(val.ukey)); PKCS5_PBKDF2_HMAC_SHA1(password, strlen(password), (unsigned char*)salt, PKCS5_SALT_LEN, PKCS5_DEFAULT_ITER, MAX_KEY, (unsigned char*)val.ukey); ret = ioctl(fd, NFS4_IOCTL_SETKEY, &val); if (ret < 0) { perror("ioctl"); } close(fd); exit(ret); }