comparison src/fileio.c @ 2265:b7cb69ab616d vim73

Added salt to blowfish encryption.
author Bram Moolenaar <bram@vim.org>
date Sun, 13 Jun 2010 05:20:42 +0200
parents 06a7438b3ef7
children ae2e615a7320
comparison
equal deleted inserted replaced
2264:0256b9c93e87 2265:b7cb69ab616d
35 #ifdef FEAT_CRYPT 35 #ifdef FEAT_CRYPT
36 /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */ 36 /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
37 static char *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"}; 37 static char *crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
38 static char crypt_magic_head[] = "VimCrypt~"; 38 static char crypt_magic_head[] = "VimCrypt~";
39 # define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */ 39 # define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */
40
41 /* For blowfish, after the magic header, we store 8 bytes of salt and then 8
42 * bytes of seed (initialisation vector). */
43 static int crypt_salt_len[] = {0, 8};
40 static int crypt_seed_len[] = {0, 8}; 44 static int crypt_seed_len[] = {0, 8};
45 #define CRYPT_SALT_LEN_MAX 8
41 #define CRYPT_SEED_LEN_MAX 8 46 #define CRYPT_SEED_LEN_MAX 8
42 #endif 47 #endif
43 48
44 /* Is there any system that doesn't have access()? */ 49 /* Is there any system that doesn't have access()? */
45 #define USE_MCH_ACCESS 50 #define USE_MCH_ACCESS
1439 * found. 1444 * found.
1440 */ 1445 */
1441 if ((filesize == 0 1446 if ((filesize == 0
1442 # ifdef FEAT_CRYPT 1447 # ifdef FEAT_CRYPT
1443 || (filesize == (CRYPT_MAGIC_LEN 1448 || (filesize == (CRYPT_MAGIC_LEN
1449 + crypt_salt_len[use_crypt_method]
1444 + crypt_seed_len[use_crypt_method]) 1450 + crypt_seed_len[use_crypt_method])
1445 && cryptkey != NULL) 1451 && cryptkey != NULL)
1446 # endif 1452 # endif
1447 ) 1453 )
1448 && (fio_flags == FIO_UCSBOM 1454 && (fio_flags == FIO_UCSBOM
2486 if (msg_add_fileformat(fileformat)) 2492 if (msg_add_fileformat(fileformat))
2487 c = TRUE; 2493 c = TRUE;
2488 #ifdef FEAT_CRYPT 2494 #ifdef FEAT_CRYPT
2489 if (cryptkey != NULL) 2495 if (cryptkey != NULL)
2490 msg_add_lines(c, (long)linecnt, filesize 2496 msg_add_lines(c, (long)linecnt, filesize
2491 - CRYPT_MAGIC_LEN - crypt_seed_len[use_crypt_method]); 2497 - CRYPT_MAGIC_LEN
2498 - crypt_salt_len[use_crypt_method]
2499 - crypt_seed_len[use_crypt_method]);
2492 else 2500 else
2493 #endif 2501 #endif
2494 msg_add_lines(c, (long)linecnt, filesize); 2502 msg_add_lines(c, (long)linecnt, filesize);
2495 2503
2496 vim_free(keep_msg); 2504 vim_free(keep_msg);
2839 { 2847 {
2840 int i; 2848 int i;
2841 2849
2842 for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++) 2850 for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++)
2843 { 2851 {
2844 if (len < (CRYPT_MAGIC_LEN + crypt_seed_len[i])) 2852 if (len < (CRYPT_MAGIC_LEN + crypt_salt_len[i] + crypt_seed_len[i]))
2845 continue; 2853 continue;
2846 if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0) 2854 if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
2847 return i; 2855 return i;
2848 } 2856 }
2849 2857
2901 } 2909 }
2902 2910
2903 if (cryptkey != NULL) 2911 if (cryptkey != NULL)
2904 { 2912 {
2905 int seed_len = crypt_seed_len[method]; 2913 int seed_len = crypt_seed_len[method];
2914 int salt_len = crypt_salt_len[method];
2906 2915
2907 if (method == 0) 2916 if (method == 0)
2908 crypt_init_keys(cryptkey); 2917 crypt_init_keys(cryptkey);
2909 else 2918 else
2910 { 2919 {
2911 bf_key_init(cryptkey); 2920 bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len);
2912 bf_ofb_init(ptr + CRYPT_MAGIC_LEN, seed_len); 2921 bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len);
2913 } 2922 }
2914 2923
2915 /* Remove magic number from the text */ 2924 /* Remove magic number from the text */
2916 *filesizep += CRYPT_MAGIC_LEN + seed_len; 2925 *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len;
2917 *sizep -= CRYPT_MAGIC_LEN + seed_len; 2926 *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len;
2918 mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + seed_len, (size_t)*sizep); 2927 mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, (size_t)*sizep);
2919 } 2928 }
2920 } 2929 }
2921 /* When starting to edit a new file which does not have encryption, clear 2930 /* When starting to edit a new file which does not have encryption, clear
2922 * the 'key' option, except when starting up (called with -x argument) */ 2931 * the 'key' option, except when starting up (called with -x argument) */
2923 else if (newfile && *curbuf->b_p_key && !starting) 2932 else if (newfile && *curbuf->b_p_key && !starting)
2933 int 2942 int
2934 prepare_crypt_read(fp) 2943 prepare_crypt_read(fp)
2935 FILE *fp; 2944 FILE *fp;
2936 { 2945 {
2937 int method; 2946 int method;
2938 char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2]; 2947 char_u buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
2948 + CRYPT_SEED_LEN_MAX + 2];
2939 2949
2940 if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1) 2950 if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
2941 return FAIL; 2951 return FAIL;
2942 method = get_crypt_method((char *)buffer, 2952 method = get_crypt_method((char *)buffer,
2943 CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX); 2953 CRYPT_MAGIC_LEN +
2954 CRYPT_SEED_LEN_MAX +
2955 CRYPT_SALT_LEN_MAX);
2944 if (method < 0 || method != curbuf->b_p_cm) 2956 if (method < 0 || method != curbuf->b_p_cm)
2945 return FAIL; 2957 return FAIL;
2946 2958
2947 if (method == 0) 2959 if (method == 0)
2948 crypt_init_keys(curbuf->b_p_key); 2960 crypt_init_keys(curbuf->b_p_key);
2949 else 2961 else
2950 { 2962 {
2963 int salt_len = crypt_salt_len[method];
2951 int seed_len = crypt_seed_len[method]; 2964 int seed_len = crypt_seed_len[method];
2952 2965
2953 if (fread(buffer, seed_len, 1, fp) != 1) 2966 if (fread(buffer, salt_len + seed_len, 1, fp) != 1)
2954 return FAIL; 2967 return FAIL;
2955 bf_key_init(curbuf->b_p_key); 2968 bf_key_init(curbuf->b_p_key, buffer, salt_len);
2956 bf_ofb_init(buffer, seed_len); 2969 bf_ofb_init(buffer + salt_len, seed_len);
2957 } 2970 }
2958 return OK; 2971 return OK;
2959 } 2972 }
2960 2973
2961 /* 2974 /*
2967 buf_T *buf; 2980 buf_T *buf;
2968 int *lenp; 2981 int *lenp;
2969 { 2982 {
2970 char_u *header; 2983 char_u *header;
2971 int seed_len = crypt_seed_len[buf->b_p_cm]; 2984 int seed_len = crypt_seed_len[buf->b_p_cm];
2972 2985 int salt_len = crypt_salt_len[buf->b_p_cm];
2973 header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SEED_LEN_MAX + 2); 2986 char_u *salt;
2987 char_u *seed;
2988
2989 header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
2990 + CRYPT_SEED_LEN_MAX + 2);
2974 if (header != NULL) 2991 if (header != NULL)
2975 { 2992 {
2976 use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */ 2993 use_crypt_method = buf->b_p_cm; /* select pkzip or blowfish */
2977 vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method], 2994 vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
2978 CRYPT_MAGIC_LEN); 2995 CRYPT_MAGIC_LEN);
2979 if (buf->b_p_cm == 0) 2996 if (buf->b_p_cm == 0)
2980 crypt_init_keys(buf->b_p_key); 2997 crypt_init_keys(buf->b_p_key);
2981 else 2998 else
2982 { 2999 {
2983 /* Using blowfish, add seed. */ 3000 /* Using blowfish, add salt and seed. */
2984 sha2_seed(header + CRYPT_MAGIC_LEN, seed_len); /* create iv */ 3001 salt = header + CRYPT_MAGIC_LEN;
2985 bf_ofb_init(header + CRYPT_MAGIC_LEN, seed_len); 3002 seed = salt + salt_len;
2986 bf_key_init(buf->b_p_key); 3003 sha2_seed(salt, salt_len, seed, seed_len);
2987 } 3004 bf_key_init(buf->b_p_key, salt, salt_len);
2988 } 3005 bf_ofb_init(seed, seed_len);
2989 *lenp = CRYPT_MAGIC_LEN + seed_len; 3006 }
3007 }
3008 *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len;
2990 return header; 3009 return header;
2991 } 3010 }
3011
3012 #endif /* FEAT_CRYPT */
2992 3013
2993 /* 3014 /*
2994 * Like fwrite() but crypt the bytes when 'key' is set. 3015 * Like fwrite() but crypt the bytes when 'key' is set.
2995 * Returns 1 if successful. 3016 * Returns 1 if successful.
2996 */ 3017 */
2997 size_t 3018 size_t
2998 fwrite_crypt(buf, ptr, len, fp) 3019 fwrite_crypt(buf, ptr, len, fp)
2999 buf_T *buf; 3020 buf_T *buf UNUSED;
3000 char_u *ptr; 3021 char_u *ptr;
3001 size_t len; 3022 size_t len;
3002 FILE *fp; 3023 FILE *fp;
3003 { 3024 {
3025 #ifdef FEAT_CRYPT
3004 char_u *copy; 3026 char_u *copy;
3005 char_u small_buf[100]; 3027 char_u small_buf[100];
3006 size_t i; 3028 size_t i;
3007 3029
3008 if (*buf->b_p_key == NUL) 3030 if (*buf->b_p_key == NUL)
3018 crypt_encode(ptr, len, copy); 3040 crypt_encode(ptr, len, copy);
3019 i = fwrite(copy, len, (size_t)1, fp); 3041 i = fwrite(copy, len, (size_t)1, fp);
3020 if (copy != small_buf) 3042 if (copy != small_buf)
3021 vim_free(copy); 3043 vim_free(copy);
3022 return i; 3044 return i;
3045 #else
3046 return fwrite(ptr, len, (size_t)1, fp);
3047 #endif
3023 } 3048 }
3024 3049
3025 /* 3050 /*
3026 * Read a string of length "len" from "fd". 3051 * Read a string of length "len" from "fd".
3027 * When 'key' is set decrypt the bytes. 3052 * When 'key' is set decrypt the bytes.
3028 */ 3053 */
3029 char_u * 3054 char_u *
3030 read_string_decrypt(buf, fd, len) 3055 read_string_decrypt(buf, fd, len)
3031 buf_T *buf; 3056 buf_T *buf UNUSED;
3032 FILE *fd; 3057 FILE *fd;
3033 int len; 3058 int len;
3034 { 3059 {
3035 char_u *ptr; 3060 char_u *ptr;
3036 3061
3037 ptr = read_string(fd, len); 3062 ptr = read_string(fd, len);
3063 #ifdef FEAT_CRYPT
3038 if (ptr != NULL || *buf->b_p_key != NUL) 3064 if (ptr != NULL || *buf->b_p_key != NUL)
3039 crypt_decode(ptr, len); 3065 crypt_decode(ptr, len);
3066 #endif
3040 return ptr; 3067 return ptr;
3041 } 3068 }
3042 3069
3043 #endif /* FEAT_CRYPT */
3044 3070
3045 #ifdef UNIX 3071 #ifdef UNIX
3046 static void 3072 static void
3047 set_file_time(fname, atime, mtime) 3073 set_file_time(fname, atime, mtime)
3048 char_u *fname; 3074 char_u *fname;