Mercurial > vim
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 |