From 4dde3df4d34c7e749123ceab7b7469674ac9c7ad Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:35:45 -0800 Subject: [PATCH] Update to libsignal 0.60.2 Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com> --- ACKNOWLEDGMENTS.md | 2 +- package-lock.json | 8 +++--- package.json | 2 +- ts/Crypto.ts | 46 ------------------------------ ts/jobs/AttachmentBackupManager.ts | 11 ++++--- ts/services/backups/crypto.ts | 21 ++++++++++++++ 6 files changed, 32 insertions(+), 58 deletions(-) diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index f39cb3ef56f7..14dd7770750d 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -4300,7 +4300,7 @@ For more information on this, and how to apply and follow the GNU AGPL, see ``` -## libsignal-account-keys 0.1.0, attest 0.1.0, libsignal-ffi 0.60.1, libsignal-jni 0.60.1, libsignal-jni-testing 0.60.1, libsignal-node 0.60.1, signal-neon-futures 0.1.0, signal-neon-futures-tests 0.1.0, libsignal-bridge 0.1.0, libsignal-bridge-macros 0.1.0, libsignal-bridge-testing 0.1.0, libsignal-bridge-types 0.1.0, libsignal-core 0.1.0, signal-crypto 0.1.0, device-transfer 0.1.0, libsignal-keytrans 0.0.1, signal-media 0.1.0, libsignal-message-backup 0.1.0, libsignal-message-backup-macros 0.1.0, libsignal-net 0.1.0, libsignal-net-infra 0.1.0, poksho 0.7.0, libsignal-protocol 0.1.0, libsignal-svr3 0.1.0, usernames 0.1.0, zkcredential 0.1.0, zkgroup 0.9.0 +## libsignal-account-keys 0.1.0, attest 0.1.0, libsignal-ffi 0.60.2, libsignal-jni 0.60.2, libsignal-jni-testing 0.60.2, libsignal-node 0.60.2, signal-neon-futures 0.1.0, signal-neon-futures-tests 0.1.0, libsignal-bridge 0.1.0, libsignal-bridge-macros 0.1.0, libsignal-bridge-testing 0.1.0, libsignal-bridge-types 0.1.0, libsignal-core 0.1.0, signal-crypto 0.1.0, device-transfer 0.1.0, libsignal-keytrans 0.0.1, signal-media 0.1.0, libsignal-message-backup 0.1.0, libsignal-message-backup-macros 0.1.0, libsignal-net 0.1.0, libsignal-net-infra 0.1.0, poksho 0.7.0, libsignal-protocol 0.1.0, libsignal-svr3 0.1.0, usernames 0.1.0, zkcredential 0.1.0, zkgroup 0.9.0 ``` GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/package-lock.json b/package-lock.json index 3a0ab39289e1..ea9e3e8c0505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@react-aria/utils": "3.16.0", "@react-spring/web": "9.5.5", "@signalapp/better-sqlite3": "9.0.8", - "@signalapp/libsignal-client": "0.60.1", + "@signalapp/libsignal-client": "0.60.2", "@signalapp/ringrtc": "2.48.4", "@types/fabric": "4.5.3", "backbone": "1.4.0", @@ -7274,9 +7274,9 @@ } }, "node_modules/@signalapp/libsignal-client": { - "version": "0.60.1", - "resolved": "https://registry.npmjs.org/@signalapp/libsignal-client/-/libsignal-client-0.60.1.tgz", - "integrity": "sha512-euLw0lFVyqSFeA/hYwr0RHDIsFKNVPTYDMr9JT1hG4oflYdzeesgPxqsJNDMio4esQGUSKcXxtw2gjsl+Qczfg==", + "version": "0.60.2", + "resolved": "https://registry.npmjs.org/@signalapp/libsignal-client/-/libsignal-client-0.60.2.tgz", + "integrity": "sha512-tU4kNP/yCwkFntb2ahXOSQJtzdy+YifAB2yv5hw0qyKSidRHLn6bYiz4Zo2tjxLDRoBLAUxCRsQramStiqNZdA==", "hasInstallScript": true, "license": "AGPL-3.0-only", "dependencies": { diff --git a/package.json b/package.json index 40f6ed001c5d..18adc9f27bf5 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "@react-aria/utils": "3.16.0", "@react-spring/web": "9.5.5", "@signalapp/better-sqlite3": "9.0.8", - "@signalapp/libsignal-client": "0.60.1", + "@signalapp/libsignal-client": "0.60.2", "@signalapp/ringrtc": "2.48.4", "@types/fabric": "4.5.3", "backbone": "1.4.0", diff --git a/ts/Crypto.ts b/ts/Crypto.ts index ce4ce2dae79c..5654c009ea23 100644 --- a/ts/Crypto.ts +++ b/ts/Crypto.ts @@ -155,52 +155,6 @@ export function decryptDeviceName( return Bytes.toString(plaintext); } -const BACKUP_KEY_LEN = 32; -const BACKUP_MEDIA_THUMBNAIL_ENCRYPT_INFO = - '20241030_SIGNAL_BACKUPS_ENCRYPT_THUMBNAIL:'; -const BACKUP_MEDIA_AES_KEY_LEN = 32; -const BACKUP_MEDIA_MAC_KEY_LEN = 32; -const BACKUP_MEDIA_IV_LEN = 16; - -export type BackupMediaKeyMaterialType = Readonly<{ - aesKey: Uint8Array; - macKey: Uint8Array; -}>; - -export function deriveBackupMediaThumbnailInnerEncryptionKeyMaterial( - mediaRootKey: Uint8Array, - mediaId: Uint8Array -): BackupMediaKeyMaterialType { - if (mediaRootKey.byteLength !== BACKUP_KEY_LEN) { - throw new Error( - 'deriveBackupMediaThumbnailKeyMaterial: invalid backup key length' - ); - } - - if (!mediaId.length) { - throw new Error('deriveBackupMediaThumbnailKeyMaterial: mediaId missing'); - } - - const hkdf = HKDF.new(3); - const material = hkdf.deriveSecrets( - BACKUP_MEDIA_MAC_KEY_LEN + BACKUP_MEDIA_AES_KEY_LEN + BACKUP_MEDIA_IV_LEN, - Buffer.from(mediaRootKey), - Buffer.concat([ - Buffer.from(BACKUP_MEDIA_THUMBNAIL_ENCRYPT_INFO), - Buffer.from(mediaId), - ]), - Buffer.alloc(0) - ); - - return { - aesKey: material.subarray(0, BACKUP_MEDIA_AES_KEY_LEN), - macKey: material.subarray( - BACKUP_MEDIA_AES_KEY_LEN, - BACKUP_MEDIA_AES_KEY_LEN + BACKUP_MEDIA_MAC_KEY_LEN - ), - }; -} - export function deriveMasterKey(accountEntropyPool: string): Uint8Array { return AccountEntropyPool.deriveSvrKey(accountEntropyPool); } diff --git a/ts/jobs/AttachmentBackupManager.ts b/ts/jobs/AttachmentBackupManager.ts index 5a4244900ca8..bf576846f6a1 100644 --- a/ts/jobs/AttachmentBackupManager.ts +++ b/ts/jobs/AttachmentBackupManager.ts @@ -25,10 +25,10 @@ import { decryptAttachmentV2ToSink, ReencryptedDigestMismatchError, } from '../AttachmentCrypto'; -import { deriveBackupMediaThumbnailInnerEncryptionKeyMaterial } from '../Crypto'; import { getBackupMediaRootKey, deriveBackupMediaKeyMaterial, + deriveBackupThumbnailTransitKeyMaterial, } from '../services/backups/crypto'; import { type AttachmentBackupJobType, @@ -432,11 +432,10 @@ async function backupThumbnailAttachment( return; } - const { aesKey, macKey } = - deriveBackupMediaThumbnailInnerEncryptionKeyMaterial( - getBackupMediaRootKey().serialize(), - mediaId.bytes - ); + const { aesKey, macKey } = deriveBackupThumbnailTransitKeyMaterial( + getBackupMediaRootKey(), + mediaId.bytes + ); log.info(`${logId}: uploading thumbnail to transit tier`); const uploadResult = await uploadThumbnailToTransitTier({ diff --git a/ts/services/backups/crypto.ts b/ts/services/backups/crypto.ts index d23ccab67f86..02ccfd059d2f 100644 --- a/ts/services/backups/crypto.ts +++ b/ts/services/backups/crypto.ts @@ -104,3 +104,24 @@ export function deriveBackupMediaKeyMaterial( ), }; } + +export function deriveBackupThumbnailTransitKeyMaterial( + mediaRootKey: BackupKey, + mediaId: Uint8Array +): BackupMediaKeyMaterialType { + if (!mediaId.length) { + throw new Error('deriveBackupThumbnailTransitKeyMaterial: mediaId missing'); + } + + const material = mediaRootKey.deriveThumbnailTransitEncryptionKey( + Buffer.from(mediaId) + ); + + return { + macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN), + aesKey: material.subarray( + BACKUP_MEDIA_MAC_KEY_LEN, + BACKUP_MEDIA_MAC_KEY_LEN + BACKUP_MEDIA_AES_KEY_LEN + ), + }; +}