comparison src/crypt.c @ 32719:185f2a160d5d v9.0.1682

patch 9.0.1682: sodium encryption is not portable Commit: https://github.com/vim/vim/commit/6019fed0c50a31f0f9bb6c80e4e2b97d3f71565a Author: Christian Brabandt <cb@256bit.org> Date: Tue Jul 11 22:38:29 2023 +0200 patch 9.0.1682: sodium encryption is not portable Problem: crypt: sodium encryption is not portable Solution: use little-endian byte order for sodium encrypted files As mentioned in #12586, sodium encryption only works on little ending architectures, because reading and writing the sodium encryption parameters are stored in the encrypted files in an arch-dependent way. This of course fails for big-endian architectures like s390. So make sure to use little-endian byte order when reading and writing sodium encrypted files. fixes: #12586 closes: 12655
author Christian Brabandt <cb@256bit.org>
date Wed, 09 Aug 2023 21:45:03 +0200
parents 4091ae33b9ec
children cb88e5c589d0
comparison
equal deleted inserted replaced
32718:3dd63e73de28 32719:185f2a160d5d
75 } cryptmethod_T; 75 } cryptmethod_T;
76 76
77 static int crypt_sodium_init_(cryptstate_T *state, char_u *key, crypt_arg_T *arg); 77 static int crypt_sodium_init_(cryptstate_T *state, char_u *key, crypt_arg_T *arg);
78 static long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last); 78 static long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
79 static long crypt_sodium_buffer_encode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last); 79 static long crypt_sodium_buffer_encode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
80 # if defined(FEAT_SODIUM) || defined(PROTO)
81 static void crypt_long_long_to_char(long long n, char_u *s);
82 static void crypt_int_to_char(int n, char_u *s);
83 static long long crypt_char_to_long_long(char_u *s);
84 static int crypt_char_to_int(char_u *s);
85 #endif
80 #if defined(FEAT_EVAL) && defined(FEAT_SODIUM) 86 #if defined(FEAT_EVAL) && defined(FEAT_SODIUM)
81 static void crypt_sodium_report_hash_params(unsigned long long opslimit, unsigned long long ops_def, size_t memlimit, size_t mem_def, int alg, int alg_def); 87 static void crypt_sodium_report_hash_params(unsigned long long opslimit, unsigned long long ops_def, size_t memlimit, size_t mem_def, int alg, int alg_def);
82 #endif 88 #endif
83 89
84 // index is method_nr of cryptstate_T, CRYPT_M_* 90 // index is method_nr of cryptstate_T, CRYPT_M_*
964 return FAIL; 970 return FAIL;
965 } 971 }
966 // "cat_add" should not be NULL, check anyway for safety 972 // "cat_add" should not be NULL, check anyway for safety
967 if (state->method_nr == CRYPT_M_SOD2 && arg->cat_add != NULL) 973 if (state->method_nr == CRYPT_M_SOD2 && arg->cat_add != NULL)
968 { 974 {
969 memcpy(arg->cat_add, &opslimit, sizeof(opslimit)); 975 char_u buffer[20];
970 arg->cat_add += sizeof(opslimit); 976 char_u *p = buffer;
971 977 vim_memset(buffer, 0, 20);
972 memcpy(arg->cat_add, &memlimit, sizeof(memlimit)); 978
973 arg->cat_add += sizeof(memlimit); 979 crypt_long_long_to_char(opslimit, p);
974 980 p += sizeof(opslimit);
975 memcpy(arg->cat_add, &alg, sizeof(alg)); 981
976 arg->cat_add += sizeof(alg); 982 crypt_long_long_to_char(memlimit, p);
983 p += sizeof(memlimit);
984
985 crypt_int_to_char(alg, p);
986 memcpy(arg->cat_add, buffer, sizeof(opslimit) + sizeof(memlimit) + sizeof(alg));
977 } 987 }
978 } 988 }
979 else 989 else
980 { 990 {
991 char_u buffer[20];
992 char_u *p = buffer;
993 vim_memset(buffer, 0, 20);
994 int size = sizeof(opslimit) +
995 sizeof(memlimit) + sizeof(alg);
996
981 // Reading parameters from file 997 // Reading parameters from file
982 if (arg->cat_add_len 998 if (arg->cat_add_len < size)
983 < (int)(sizeof(opslimit) + sizeof(memlimit) + sizeof(alg)))
984 { 999 {
985 sodium_free(sd_state); 1000 sodium_free(sd_state);
986 return FAIL; 1001 return FAIL;
987 } 1002 }
988 1003
989 // derive the key from the file header 1004 // derive the key from the file header
990 memcpy(&opslimit, arg->cat_add, sizeof(opslimit)); 1005 memcpy(p, arg->cat_add, size);
991 arg->cat_add += sizeof(opslimit); 1006 arg->cat_add += size;
992 1007
993 memcpy(&memlimit, arg->cat_add, sizeof(memlimit)); 1008 opslimit = crypt_char_to_long_long(p);
994 arg->cat_add += sizeof(memlimit); 1009 p += sizeof(opslimit);
995 1010 memlimit = crypt_char_to_long_long(p);
996 memcpy(&alg, arg->cat_add, sizeof(alg)); 1011 p += sizeof(memlimit);
997 arg->cat_add += sizeof(alg); 1012 alg = crypt_char_to_int(p);
1013 p += sizeof(alg);
998 1014
999 #ifdef FEAT_EVAL 1015 #ifdef FEAT_EVAL
1000 crypt_sodium_report_hash_params(opslimit, 1016 crypt_sodium_report_hash_params(opslimit,
1001 crypto_pwhash_OPSLIMIT_INTERACTIVE, 1017 crypto_pwhash_OPSLIMIT_INTERACTIVE,
1002 (size_t)memlimit, crypto_pwhash_MEMLIMIT_INTERACTIVE, 1018 (size_t)memlimit, crypto_pwhash_MEMLIMIT_INTERACTIVE,
1325 smsg(_("xchacha20v2: using default algorithm \"%d\" for Key derivation."), alg); 1341 smsg(_("xchacha20v2: using default algorithm \"%d\" for Key derivation."), alg);
1326 verbose_leave(); 1342 verbose_leave();
1327 } 1343 }
1328 } 1344 }
1329 #endif 1345 #endif
1346
1347 static void
1348 crypt_long_long_to_char(long long n, char_u *s)
1349 {
1350 int i;
1351 for (i = 0; i < 8; i++)
1352 {
1353 s[i] = (char_u)(n & 0xff);
1354 n = (unsigned)n >> 8;
1355 }
1356 }
1357
1358 static void
1359 crypt_int_to_char(int n, char_u *s)
1360 {
1361 int i;
1362 for (i = 0; i < 4; i++)
1363 {
1364 s[i] = (char_u)(n & 0xff);
1365 n = (unsigned)n >> 8;
1366 }
1367 }
1368
1369 static long long
1370 crypt_char_to_long_long(char_u *s)
1371 {
1372 unsigned long long retval = 0;
1373 int i;
1374 for (i = 7; i >= 0; i--)
1375 {
1376 if (i == 7)
1377 retval = s[i];
1378 else
1379 retval |= s[i];
1380 if (i > 0)
1381 retval <<= 8;
1382 }
1383 return retval;
1384 }
1385
1386 static int
1387 crypt_char_to_int(char_u *s)
1388 {
1389 int retval = 0;
1390 int i;
1391
1392 for (i = 3; i >= 0; i--)
1393 {
1394 if (i == 3)
1395 retval = s[i];
1396 else
1397 retval |= s[i];
1398 if (i > 0)
1399 retval <<= 8;
1400 }
1401 return retval;
1402 }
1330 # endif 1403 # endif
1331 1404
1332 #endif // FEAT_CRYPT 1405 #endif // FEAT_CRYPT