comparison src/memline.c @ 24970:7e9e53a0368f v8.2.3022

patch 8.2.3022: available encryption methods are not strong enough Commit: https://github.com/vim/vim/commit/f573c6e1ed58d46d694c802eaf5ae3662a952744 Author: Christian Brabandt <cb@256bit.org> Date: Sun Jun 20 14:02:16 2021 +0200 patch 8.2.3022: available encryption methods are not strong enough Problem: Available encryption methods are not strong enough. Solution: Add initial support for xchaha20. (Christian Brabandt, closes #8394)
author Bram Moolenaar <Bram@vim.org>
date Sun, 20 Jun 2021 14:15:07 +0200
parents a81b883576d6
children 85d1e82ed134
comparison
equal deleted inserted replaced
24969:445ed84ae76a 24970:7e9e53a0368f
46 46
47 #ifndef UNIX // it's in os_unix.h for Unix 47 #ifndef UNIX // it's in os_unix.h for Unix
48 # include <time.h> 48 # include <time.h>
49 #endif 49 #endif
50 50
51 // for randombytes_buf
52 #ifdef FEAT_SODIUM
53 # include <sodium.h>
54 #endif
55
51 #if defined(SASC) || defined(__amigaos4__) 56 #if defined(SASC) || defined(__amigaos4__)
52 # include <proto/dos.h> // for Open() and Close() 57 # include <proto/dos.h> // for Open() and Close()
53 #endif 58 #endif
54 59
55 typedef struct block0 ZERO_BL; // contents of the first block 60 typedef struct block0 ZERO_BL; // contents of the first block
62 #define BLOCK0_ID0 'b' // block 0 id 0 67 #define BLOCK0_ID0 'b' // block 0 id 0
63 #define BLOCK0_ID1 '0' // block 0 id 1 68 #define BLOCK0_ID1 '0' // block 0 id 1
64 #define BLOCK0_ID1_C0 'c' // block 0 id 1 'cm' 0 69 #define BLOCK0_ID1_C0 'c' // block 0 id 1 'cm' 0
65 #define BLOCK0_ID1_C1 'C' // block 0 id 1 'cm' 1 70 #define BLOCK0_ID1_C1 'C' // block 0 id 1 'cm' 1
66 #define BLOCK0_ID1_C2 'd' // block 0 id 1 'cm' 2 71 #define BLOCK0_ID1_C2 'd' // block 0 id 1 'cm' 2
72 #define BLOCK0_ID1_C3 'S' // block 0 id 1 'cm' 3 - but not actually used
67 73
68 #if defined(FEAT_CRYPT) 74 #if defined(FEAT_CRYPT)
69 static int id1_codes[] = { 75 static int id1_codes[] = {
70 BLOCK0_ID1_C0, // CRYPT_M_ZIP 76 BLOCK0_ID1_C0, // CRYPT_M_ZIP
71 BLOCK0_ID1_C1, // CRYPT_M_BF 77 BLOCK0_ID1_C1, // CRYPT_M_BF
72 BLOCK0_ID1_C2, // CRYPT_M_BF2 78 BLOCK0_ID1_C2, // CRYPT_M_BF2
79 BLOCK0_ID1_C3, // CRYPT_M_SOD - Unused!
73 }; 80 };
74 #endif 81 #endif
75 82
76 /* 83 /*
77 * pointer to a block, used in a pointer block 84 * pointer to a block, used in a pointer block
424 { 431 {
425 if (*buf->b_p_key != NUL) 432 if (*buf->b_p_key != NUL)
426 { 433 {
427 int method_nr = crypt_get_method_nr(buf); 434 int method_nr = crypt_get_method_nr(buf);
428 435
429 if (method_nr > CRYPT_M_ZIP) 436 if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD)
430 { 437 {
431 // Generate a seed and store it in the memfile. 438 // Generate a seed and store it in the memfile.
432 sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0); 439 sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
433 } 440 }
441 #ifdef FEAT_SODIUM
442 else if (method_nr == CRYPT_M_SOD)
443 randombytes_buf(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN);
444 #endif
434 } 445 }
435 } 446 }
436 447
437 /* 448 /*
438 * Prepare encryption for "buf" with block 0 "b0p". 449 * Prepare encryption for "buf" with block 0 "b0p".
445 else 456 else
446 { 457 {
447 int method_nr = crypt_get_method_nr(buf); 458 int method_nr = crypt_get_method_nr(buf);
448 459
449 b0p->b0_id[1] = id1_codes[method_nr]; 460 b0p->b0_id[1] = id1_codes[method_nr];
450 if (method_nr > CRYPT_M_ZIP) 461 if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD)
451 { 462 {
452 // Generate a seed and store it in block 0 and in the memfile. 463 // Generate a seed and store it in block 0 and in the memfile.
453 sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0); 464 sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
454 mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN); 465 mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
455 } 466 }
480 DATA_BL *dp; 491 DATA_BL *dp;
481 blocknr_T bnum; 492 blocknr_T bnum;
482 int top; 493 int top;
483 int old_method; 494 int old_method;
484 495
485 if (mfp == NULL) 496 if (mfp == NULL || mfp->mf_fd < 0)
486 return; // no memfile yet, nothing to do 497 return; // no memfile yet, nothing to do
487 old_method = crypt_method_nr_from_name(old_cm); 498 old_method = crypt_method_nr_from_name(old_cm);
488 499
500 if (old_method == CRYPT_M_SOD || crypt_get_method_nr(buf) == CRYPT_M_SOD)
501 {
502 // close the swapfile
503 mf_close_file(buf, TRUE);
504 buf->b_p_swf = FALSE;
505 return;
506 }
489 // First make sure the swapfile is in a consistent state, using the old 507 // First make sure the swapfile is in a consistent state, using the old
490 // key and method. 508 // key and method.
491 { 509 {
492 char_u *new_key = buf->b_p_key; 510 char_u *new_key = buf->b_p_key;
493 char_u *new_buf_cm = buf->b_p_cm; 511 char_u *new_buf_cm = buf->b_p_cm;
909 { 927 {
910 if (b0p->b0_id[0] != BLOCK0_ID0 928 if (b0p->b0_id[0] != BLOCK0_ID0
911 || (b0p->b0_id[1] != BLOCK0_ID1 929 || (b0p->b0_id[1] != BLOCK0_ID1
912 && b0p->b0_id[1] != BLOCK0_ID1_C0 930 && b0p->b0_id[1] != BLOCK0_ID1_C0
913 && b0p->b0_id[1] != BLOCK0_ID1_C1 931 && b0p->b0_id[1] != BLOCK0_ID1_C1
914 && b0p->b0_id[1] != BLOCK0_ID1_C2) 932 && b0p->b0_id[1] != BLOCK0_ID1_C2
933 && b0p->b0_id[1] != BLOCK0_ID1_C3)
915 ) 934 )
916 return FAIL; 935 return FAIL;
917 return OK; 936 return OK;
918 } 937 }
919 938
2400 buf_T *buf; 2419 buf_T *buf;
2401 stat_T st; 2420 stat_T st;
2402 2421
2403 FOR_ALL_BUFFERS(buf) 2422 FOR_ALL_BUFFERS(buf)
2404 { 2423 {
2405 if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) 2424 if (buf->b_ml.ml_mfp == NULL
2425 || buf->b_ml.ml_mfp->mf_fname == NULL
2426 || buf->b_ml.ml_mfp->mf_fd < 0)
2406 continue; // no file 2427 continue; // no file
2407 2428
2408 ml_flush_line(buf); // flush buffered line 2429 ml_flush_line(buf); // flush buffered line
2409 // flush locked block 2430 // flush locked block
2410 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); 2431 (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
5318 5339
5319 // Copy the header and the text. 5340 // Copy the header and the text.
5320 mch_memmove(new_data, dp, head_end - (char_u *)dp); 5341 mch_memmove(new_data, dp, head_end - (char_u *)dp);
5321 5342
5322 // Encrypt the text. 5343 // Encrypt the text.
5323 crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start); 5344 crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start,
5345 FALSE);
5324 crypt_free_state(state); 5346 crypt_free_state(state);
5325 5347
5326 // Clear the gap. 5348 // Clear the gap.
5327 if (head_end < text_start) 5349 if (head_end < text_start)
5328 vim_memset(new_data + (head_end - data), 0, text_start - head_end); 5350 vim_memset(new_data + (head_end - data), 0, text_start - head_end);
5358 5380
5359 state = ml_crypt_prepare(mfp, offset, TRUE); 5381 state = ml_crypt_prepare(mfp, offset, TRUE);
5360 if (state != NULL) 5382 if (state != NULL)
5361 { 5383 {
5362 // Decrypt the text in place. 5384 // Decrypt the text in place.
5363 crypt_decode_inplace(state, text_start, text_len); 5385 crypt_decode_inplace(state, text_start, text_len, FALSE);
5364 crypt_free_state(state); 5386 crypt_free_state(state);
5365 } 5387 }
5366 } 5388 }
5367 } 5389 }
5368 5390
5405 5427
5406 // Using blowfish or better: add salt and seed. We use the byte offset 5428 // Using blowfish or better: add salt and seed. We use the byte offset
5407 // of the block for the salt. 5429 // of the block for the salt.
5408 vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); 5430 vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
5409 return crypt_create(method_nr, key, salt, (int)STRLEN(salt), 5431 return crypt_create(method_nr, key, salt, (int)STRLEN(salt),
5410 seed, MF_SEED_LEN); 5432 seed, MF_SEED_LEN);
5411 } 5433 }
5412 5434
5413 #endif 5435 #endif
5414 5436
5415 5437