Changeset 46858 for trunk/src/wp-includes/sodium_compat/src/Crypto.php
- Timestamp:
- 12/09/2019 04:40:11 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/sodium_compat/src/Crypto.php
r46586 r46858 779 779 780 780 /** 781 * Initialize a hashing context for BLAKE2b. 782 * 783 * @internal Do not use this directly. Use ParagonIE_Sodium_Compat. 784 * 785 * @param string $key 786 * @param int $outputLength 787 * @param string $salt 788 * @param string $personal 789 * @return string 790 * @throws RangeException 791 * @throws SodiumException 792 * @throws TypeError 793 */ 794 public static function generichash_init_salt_personal( 795 $key = '', 796 $outputLength = 32, 797 $salt = '', 798 $personal = '' 799 ) { 800 // This ensures that ParagonIE_Sodium_Core_BLAKE2b::$iv is initialized 801 ParagonIE_Sodium_Core_BLAKE2b::pseudoConstructor(); 802 803 $k = null; 804 if (!empty($key)) { 805 $k = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($key); 806 if ($k->count() > ParagonIE_Sodium_Core_BLAKE2b::KEYBYTES) { 807 throw new RangeException('Invalid key size'); 808 } 809 } 810 if (!empty($salt)) { 811 $s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($salt); 812 } else { 813 $s = null; 814 } 815 if (!empty($salt)) { 816 $p = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($personal); 817 } else { 818 $p = null; 819 } 820 821 /** @var SplFixedArray $ctx */ 822 $ctx = ParagonIE_Sodium_Core_BLAKE2b::init($k, $outputLength, $s, $p); 823 824 return ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx); 825 } 826 827 /** 781 828 * Update a hashing context for BLAKE2b with $message 782 829 * … … 1187 1234 1188 1235 /** 1236 * @param string $key 1237 * @return array<int, string> Returns a state and a header. 1238 * @throws Exception 1239 * @throws SodiumException 1240 */ 1241 public static function secretstream_xchacha20poly1305_init_push($key) 1242 { 1243 # randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); 1244 $out = random_bytes(24); 1245 1246 # crypto_core_hchacha20(state->k, out, k, NULL); 1247 $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20($out, $key); 1248 $state = new ParagonIE_Sodium_Core_SecretStream_State( 1249 $subkey, 1250 ParagonIE_Sodium_Core_Util::substr($out, 16, 8) . str_repeat("\0", 4) 1251 ); 1252 1253 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1254 $state->counterReset(); 1255 1256 # memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, 1257 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1258 # memset(state->_pad, 0, sizeof state->_pad); 1259 return array( 1260 $state->toString(), 1261 $out 1262 ); 1263 } 1264 1265 /** 1266 * @param string $key 1267 * @param string $header 1268 * @return string Returns a state. 1269 * @throws Exception 1270 */ 1271 public static function secretstream_xchacha20poly1305_init_pull($key, $header) 1272 { 1273 # crypto_core_hchacha20(state->k, in, k, NULL); 1274 $subkey = ParagonIE_Sodium_Core_HChaCha20::hChaCha20( 1275 ParagonIE_Sodium_Core_Util::substr($header, 0, 16), 1276 $key 1277 ); 1278 $state = new ParagonIE_Sodium_Core_SecretStream_State( 1279 $subkey, 1280 ParagonIE_Sodium_Core_Util::substr($header, 16) 1281 ); 1282 $state->counterReset(); 1283 # memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, 1284 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1285 # memset(state->_pad, 0, sizeof state->_pad); 1286 # return 0; 1287 return $state->toString(); 1288 } 1289 1290 /** 1291 * @param string $state 1292 * @param string $msg 1293 * @param string $aad 1294 * @param int $tag 1295 * @return string 1296 * @throws SodiumException 1297 */ 1298 public static function secretstream_xchacha20poly1305_push(&$state, $msg, $aad = '', $tag = 0) 1299 { 1300 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1301 # crypto_onetimeauth_poly1305_state poly1305_state; 1302 # unsigned char block[64U]; 1303 # unsigned char slen[8U]; 1304 # unsigned char *c; 1305 # unsigned char *mac; 1306 1307 $msglen = ParagonIE_Sodium_Core_Util::strlen($msg); 1308 $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); 1309 1310 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1311 throw new SodiumException( 1312 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1313 ); 1314 } 1315 1316 # if (outlen_p != NULL) { 1317 # *outlen_p = 0U; 1318 # } 1319 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1320 # sodium_misuse(); 1321 # } 1322 1323 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1324 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1325 # sodium_memzero(block, sizeof block); 1326 $auth = new ParagonIE_Sodium_Core_Poly1305_State( 1327 ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1328 ); 1329 1330 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1331 $auth->update($aad); 1332 1333 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1334 # (0x10 - adlen) & 0xf); 1335 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1336 1337 # memset(block, 0, sizeof block); 1338 # block[0] = tag; 1339 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1340 # state->nonce, 1U, state->k); 1341 $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1342 ParagonIE_Sodium_Core_Util::intToChr($tag) . str_repeat("\0", 63), 1343 $st->getCombinedNonce(), 1344 $st->getKey(), 1345 ParagonIE_Sodium_Core_Util::store64_le(1) 1346 ); 1347 1348 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1349 $auth->update($block); 1350 1351 # out[0] = block[0]; 1352 $out = $block[0]; 1353 # c = out + (sizeof tag); 1354 # crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); 1355 $cipher = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1356 $msg, 1357 $st->getCombinedNonce(), 1358 $st->getKey(), 1359 ParagonIE_Sodium_Core_Util::store64_le(2) 1360 ); 1361 1362 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1363 $auth->update($cipher); 1364 1365 $out .= $cipher; 1366 unset($cipher); 1367 1368 # crypto_onetimeauth_poly1305_update 1369 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1370 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1371 1372 # STORE64_LE(slen, (uint64_t) adlen); 1373 $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); 1374 1375 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1376 $auth->update($slen); 1377 1378 # STORE64_LE(slen, (sizeof block) + mlen); 1379 $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); 1380 1381 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1382 $auth->update($slen); 1383 1384 # mac = c + mlen; 1385 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1386 $mac = $auth->finish(); 1387 $out .= $mac; 1388 1389 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1390 unset($auth); 1391 1392 1393 # XOR_BUF(STATE_INONCE(state), mac, 1394 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1395 $st->xorNonce($mac); 1396 1397 # sodium_increment(STATE_COUNTER(state), 1398 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1399 $st->incrementCounter(); 1400 // Overwrite by reference: 1401 $state = $st->toString(); 1402 1403 /** @var bool $rekey */ 1404 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1405 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1406 # sodium_is_zero(STATE_COUNTER(state), 1407 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1408 # crypto_secretstream_xchacha20poly1305_rekey(state); 1409 # } 1410 if ($rekey || $st->needsRekey()) { 1411 // DO REKEY 1412 self::secretstream_xchacha20poly1305_rekey($state); 1413 } 1414 # if (outlen_p != NULL) { 1415 # *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; 1416 # } 1417 return $out; 1418 } 1419 1420 /** 1421 * @param string $state 1422 * @param string $cipher 1423 * @param string $aad 1424 * @return bool|array{0: string, 1: int} 1425 * @throws SodiumException 1426 */ 1427 public static function secretstream_xchacha20poly1305_pull(&$state, $cipher, $aad = '') 1428 { 1429 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1430 1431 $cipherlen = ParagonIE_Sodium_Core_Util::strlen($cipher); 1432 # mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; 1433 $msglen = $cipherlen - ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES; 1434 $aadlen = ParagonIE_Sodium_Core_Util::strlen($aad); 1435 1436 # if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { 1437 # sodium_misuse(); 1438 # } 1439 if ((($msglen + 63) >> 6) > 0xfffffffe) { 1440 throw new SodiumException( 1441 'message cannot be larger than SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX bytes' 1442 ); 1443 } 1444 1445 # crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); 1446 # crypto_onetimeauth_poly1305_init(&poly1305_state, block); 1447 # sodium_memzero(block, sizeof block); 1448 $auth = new ParagonIE_Sodium_Core_Poly1305_State( 1449 ParagonIE_Sodium_Core_ChaCha20::ietfStream(32, $st->getCombinedNonce(), $st->getKey()) 1450 ); 1451 1452 # crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); 1453 $auth->update($aad); 1454 1455 # crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, 1456 # (0x10 - adlen) & 0xf); 1457 $auth->update(str_repeat("\0", ((0x10 - $aadlen) & 0xf))); 1458 1459 1460 # memset(block, 0, sizeof block); 1461 # block[0] = in[0]; 1462 # crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, 1463 # state->nonce, 1U, state->k); 1464 $block = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1465 $cipher[0] . str_repeat("\0", 63), 1466 $st->getCombinedNonce(), 1467 $st->getKey(), 1468 ParagonIE_Sodium_Core_Util::store64_le(1) 1469 ); 1470 # tag = block[0]; 1471 # block[0] = in[0]; 1472 # crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); 1473 $tag = ParagonIE_Sodium_Core_Util::chrToInt($block[0]); 1474 $block[0] = $cipher[0]; 1475 $auth->update($block); 1476 1477 1478 # c = in + (sizeof tag); 1479 # crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); 1480 $auth->update(ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen)); 1481 1482 # crypto_onetimeauth_poly1305_update 1483 # (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); 1484 $auth->update(str_repeat("\0", ((0x10 - 64 + $msglen) & 0xf))); 1485 1486 # STORE64_LE(slen, (uint64_t) adlen); 1487 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1488 $slen = ParagonIE_Sodium_Core_Util::store64_le($aadlen); 1489 $auth->update($slen); 1490 1491 # STORE64_LE(slen, (sizeof block) + mlen); 1492 # crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); 1493 $slen = ParagonIE_Sodium_Core_Util::store64_le(64 + $msglen); 1494 $auth->update($slen); 1495 1496 # crypto_onetimeauth_poly1305_final(&poly1305_state, mac); 1497 # sodium_memzero(&poly1305_state, sizeof poly1305_state); 1498 $mac = $auth->finish(); 1499 1500 # stored_mac = c + mlen; 1501 # if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { 1502 # sodium_memzero(mac, sizeof mac); 1503 # return -1; 1504 # } 1505 1506 $stored = ParagonIE_Sodium_Core_Util::substr($cipher, $msglen + 1, 16); 1507 if (!ParagonIE_Sodium_Core_Util::hashEquals($mac, $stored)) { 1508 return false; 1509 } 1510 1511 # crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); 1512 $out = ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1513 ParagonIE_Sodium_Core_Util::substr($cipher, 1, $msglen), 1514 $st->getCombinedNonce(), 1515 $st->getKey(), 1516 ParagonIE_Sodium_Core_Util::store64_le(2) 1517 ); 1518 1519 # XOR_BUF(STATE_INONCE(state), mac, 1520 # crypto_secretstream_xchacha20poly1305_INONCEBYTES); 1521 $st->xorNonce($mac); 1522 1523 # sodium_increment(STATE_COUNTER(state), 1524 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES); 1525 $st->incrementCounter(); 1526 1527 # if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || 1528 # sodium_is_zero(STATE_COUNTER(state), 1529 # crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { 1530 # crypto_secretstream_xchacha20poly1305_rekey(state); 1531 # } 1532 1533 // Overwrite by reference: 1534 $state = $st->toString(); 1535 1536 /** @var bool $rekey */ 1537 $rekey = ($tag & ParagonIE_Sodium_Compat::CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY) !== 0; 1538 if ($rekey || $st->needsRekey()) { 1539 // DO REKEY 1540 self::secretstream_xchacha20poly1305_rekey($state); 1541 } 1542 return array($out, $tag); 1543 } 1544 1545 /** 1546 * @param string $state 1547 * @return void 1548 * @throws SodiumException 1549 */ 1550 public static function secretstream_xchacha20poly1305_rekey(&$state) 1551 { 1552 $st = ParagonIE_Sodium_Core_SecretStream_State::fromString($state); 1553 # unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + 1554 # crypto_secretstream_xchacha20poly1305_INONCEBYTES]; 1555 # size_t i; 1556 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1557 # new_key_and_inonce[i] = state->k[i]; 1558 # } 1559 $new_key_and_inonce = $st->getKey(); 1560 1561 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1562 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = 1563 # STATE_INONCE(state)[i]; 1564 # } 1565 $new_key_and_inonce .= ParagonIE_Sodium_Core_Util::substR($st->getNonce(), 0, 8); 1566 1567 # crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, 1568 # sizeof new_key_and_inonce, 1569 # state->nonce, state->k); 1570 1571 $st->rekey(ParagonIE_Sodium_Core_ChaCha20::ietfStreamXorIc( 1572 $new_key_and_inonce, 1573 $st->getCombinedNonce(), 1574 $st->getKey(), 1575 ParagonIE_Sodium_Core_Util::store64_le(0) 1576 )); 1577 1578 # for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { 1579 # state->k[i] = new_key_and_inonce[i]; 1580 # } 1581 # for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { 1582 # STATE_INONCE(state)[i] = 1583 # new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; 1584 # } 1585 # _crypto_secretstream_xchacha20poly1305_counter_reset(state); 1586 $st->counterReset(); 1587 1588 $state = $st->toString(); 1589 } 1590 1591 /** 1189 1592 * Detached Ed25519 signature. 1190 1593 *
Note: See TracChangeset
for help on using the changeset viewer.