xref: /linux/fs/bcachefs/checksum.c (revision 1c6fdbd8f2465ddfb73a01ec620cbf3d14044e1a)
1*1c6fdbd8SKent Overstreet // SPDX-License-Identifier: GPL-2.0
2*1c6fdbd8SKent Overstreet #include "bcachefs.h"
3*1c6fdbd8SKent Overstreet #include "checksum.h"
4*1c6fdbd8SKent Overstreet #include "super.h"
5*1c6fdbd8SKent Overstreet #include "super-io.h"
6*1c6fdbd8SKent Overstreet 
7*1c6fdbd8SKent Overstreet #include <linux/crc32c.h>
8*1c6fdbd8SKent Overstreet #include <linux/crypto.h>
9*1c6fdbd8SKent Overstreet #include <linux/key.h>
10*1c6fdbd8SKent Overstreet #include <linux/random.h>
11*1c6fdbd8SKent Overstreet #include <linux/scatterlist.h>
12*1c6fdbd8SKent Overstreet #include <crypto/algapi.h>
13*1c6fdbd8SKent Overstreet #include <crypto/chacha.h>
14*1c6fdbd8SKent Overstreet #include <crypto/hash.h>
15*1c6fdbd8SKent Overstreet #include <crypto/poly1305.h>
16*1c6fdbd8SKent Overstreet #include <crypto/skcipher.h>
17*1c6fdbd8SKent Overstreet #include <keys/user-type.h>
18*1c6fdbd8SKent Overstreet 
19*1c6fdbd8SKent Overstreet /*
20*1c6fdbd8SKent Overstreet  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group (Any
21*1c6fdbd8SKent Overstreet  * use permitted, subject to terms of PostgreSQL license; see.)
22*1c6fdbd8SKent Overstreet 
23*1c6fdbd8SKent Overstreet  * If we have a 64-bit integer type, then a 64-bit CRC looks just like the
24*1c6fdbd8SKent Overstreet  * usual sort of implementation. (See Ross Williams' excellent introduction
25*1c6fdbd8SKent Overstreet  * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
26*1c6fdbd8SKent Overstreet  * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.)
27*1c6fdbd8SKent Overstreet  * If we have no working 64-bit type, then fake it with two 32-bit registers.
28*1c6fdbd8SKent Overstreet  *
29*1c6fdbd8SKent Overstreet  * The present implementation is a normal (not "reflected", in Williams'
30*1c6fdbd8SKent Overstreet  * terms) 64-bit CRC, using initial all-ones register contents and a final
31*1c6fdbd8SKent Overstreet  * bit inversion. The chosen polynomial is borrowed from the DLT1 spec
32*1c6fdbd8SKent Overstreet  * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM):
33*1c6fdbd8SKent Overstreet  *
34*1c6fdbd8SKent Overstreet  * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
35*1c6fdbd8SKent Overstreet  * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
36*1c6fdbd8SKent Overstreet  * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
37*1c6fdbd8SKent Overstreet  * x^7 + x^4 + x + 1
38*1c6fdbd8SKent Overstreet */
39*1c6fdbd8SKent Overstreet 
40*1c6fdbd8SKent Overstreet static const u64 crc_table[256] = {
41*1c6fdbd8SKent Overstreet 	0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL,
42*1c6fdbd8SKent Overstreet 	0xC711223CFA3E5BB5ULL, 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL,
43*1c6fdbd8SKent Overstreet 	0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL, 0x9266CC8A1C85D9BEULL,
44*1c6fdbd8SKent Overstreet 	0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
45*1c6fdbd8SKent Overstreet 	0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL,
46*1c6fdbd8SKent Overstreet 	0x1C4488F3E8F96ED4ULL, 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL,
47*1c6fdbd8SKent Overstreet 	0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL, 0x2F0E1EBA9EA36930ULL,
48*1c6fdbd8SKent Overstreet 	0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
49*1c6fdbd8SKent Overstreet 	0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL,
50*1c6fdbd8SKent Overstreet 	0x334A9649765A07E4ULL, 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL,
51*1c6fdbd8SKent Overstreet 	0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL, 0xCC7AF1FF21C30BDEULL,
52*1c6fdbd8SKent Overstreet 	0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
53*1c6fdbd8SKent Overstreet 	0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL,
54*1c6fdbd8SKent Overstreet 	0x4258B586D5BFBCB4ULL, 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL,
55*1c6fdbd8SKent Overstreet 	0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL, 0x172F5B3033043EBFULL,
56*1c6fdbd8SKent Overstreet 	0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
57*1c6fdbd8SKent Overstreet 	0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL,
58*1c6fdbd8SKent Overstreet 	0x6D56AB3C4B1CD584ULL, 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL,
59*1c6fdbd8SKent Overstreet 	0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL, 0x3821458AADA7578FULL,
60*1c6fdbd8SKent Overstreet 	0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
61*1c6fdbd8SKent Overstreet 	0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL,
62*1c6fdbd8SKent Overstreet 	0xB60301F359DBE0E5ULL, 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL,
63*1c6fdbd8SKent Overstreet 	0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL, 0x93366450E42ECDF0ULL,
64*1c6fdbd8SKent Overstreet 	0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
65*1c6fdbd8SKent Overstreet 	0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL,
66*1c6fdbd8SKent Overstreet 	0x8F72ECA30CD7A324ULL, 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL,
67*1c6fdbd8SKent Overstreet 	0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL, 0xBC387AEA7A8DA4C0ULL,
68*1c6fdbd8SKent Overstreet 	0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
69*1c6fdbd8SKent Overstreet 	0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL,
70*1c6fdbd8SKent Overstreet 	0x321A3E938EF113AAULL, 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL,
71*1c6fdbd8SKent Overstreet 	0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL, 0x676DD025684A91A1ULL,
72*1c6fdbd8SKent Overstreet 	0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
73*1c6fdbd8SKent Overstreet 	0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL,
74*1c6fdbd8SKent Overstreet 	0xD16ED1D631917144ULL, 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL,
75*1c6fdbd8SKent Overstreet 	0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL, 0x84193F60D72AF34FULL,
76*1c6fdbd8SKent Overstreet 	0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
77*1c6fdbd8SKent Overstreet 	0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL,
78*1c6fdbd8SKent Overstreet 	0x0A3B7B1923564425ULL, 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL,
79*1c6fdbd8SKent Overstreet 	0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL, 0x3971ED50550C43C1ULL,
80*1c6fdbd8SKent Overstreet 	0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
81*1c6fdbd8SKent Overstreet 	0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL,
82*1c6fdbd8SKent Overstreet 	0x253565A3BDF52D15ULL, 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL,
83*1c6fdbd8SKent Overstreet 	0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL, 0xF6FAE5C07D3274CDULL,
84*1c6fdbd8SKent Overstreet 	0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
85*1c6fdbd8SKent Overstreet 	0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL,
86*1c6fdbd8SKent Overstreet 	0x78D8A1B9894EC3A7ULL, 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL,
87*1c6fdbd8SKent Overstreet 	0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL, 0x2DAF4F0F6FF541ACULL,
88*1c6fdbd8SKent Overstreet 	0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
89*1c6fdbd8SKent Overstreet 	0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL,
90*1c6fdbd8SKent Overstreet 	0x57D6BF0317EDAA97ULL, 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL,
91*1c6fdbd8SKent Overstreet 	0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL, 0x02A151B5F156289CULL,
92*1c6fdbd8SKent Overstreet 	0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
93*1c6fdbd8SKent Overstreet 	0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL,
94*1c6fdbd8SKent Overstreet 	0x8C8315CC052A9FF6ULL, 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL,
95*1c6fdbd8SKent Overstreet 	0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL, 0x73B3727A52B393CCULL,
96*1c6fdbd8SKent Overstreet 	0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
97*1c6fdbd8SKent Overstreet 	0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL,
98*1c6fdbd8SKent Overstreet 	0x6FF7FA89BA4AFD18ULL, 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL,
99*1c6fdbd8SKent Overstreet 	0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL, 0x5CBD6CC0CC10FAFCULL,
100*1c6fdbd8SKent Overstreet 	0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
101*1c6fdbd8SKent Overstreet 	0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL,
102*1c6fdbd8SKent Overstreet 	0xD29F28B9386C4D96ULL, 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL,
103*1c6fdbd8SKent Overstreet 	0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL, 0x87E8C60FDED7CF9DULL,
104*1c6fdbd8SKent Overstreet 	0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
105*1c6fdbd8SKent Overstreet 	0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL,
106*1c6fdbd8SKent Overstreet 	0xEBEEC5E96D600E57ULL, 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL,
107*1c6fdbd8SKent Overstreet 	0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL, 0xBE992B5F8BDB8C5CULL,
108*1c6fdbd8SKent Overstreet 	0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
109*1c6fdbd8SKent Overstreet 	0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL,
110*1c6fdbd8SKent Overstreet 	0x30BB6F267FA73B36ULL, 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL,
111*1c6fdbd8SKent Overstreet 	0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL, 0x03F1F96F09FD3CD2ULL,
112*1c6fdbd8SKent Overstreet 	0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
113*1c6fdbd8SKent Overstreet 	0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL,
114*1c6fdbd8SKent Overstreet 	0x1FB5719CE1045206ULL, 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL,
115*1c6fdbd8SKent Overstreet 	0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL, 0xE085162AB69D5E3CULL,
116*1c6fdbd8SKent Overstreet 	0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
117*1c6fdbd8SKent Overstreet 	0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL,
118*1c6fdbd8SKent Overstreet 	0x6EA7525342E1E956ULL, 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL,
119*1c6fdbd8SKent Overstreet 	0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL, 0x3BD0BCE5A45A6B5DULL,
120*1c6fdbd8SKent Overstreet 	0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
121*1c6fdbd8SKent Overstreet 	0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL,
122*1c6fdbd8SKent Overstreet 	0x41A94CE9DC428066ULL, 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL,
123*1c6fdbd8SKent Overstreet 	0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL, 0x14DEA25F3AF9026DULL,
124*1c6fdbd8SKent Overstreet 	0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
125*1c6fdbd8SKent Overstreet 	0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL,
126*1c6fdbd8SKent Overstreet 	0x9AFCE626CE85B507ULL,
127*1c6fdbd8SKent Overstreet };
128*1c6fdbd8SKent Overstreet 
129*1c6fdbd8SKent Overstreet u64 bch2_crc64_update(u64 crc, const void *_data, size_t len)
130*1c6fdbd8SKent Overstreet {
131*1c6fdbd8SKent Overstreet 	const unsigned char *data = _data;
132*1c6fdbd8SKent Overstreet 
133*1c6fdbd8SKent Overstreet 	while (len--) {
134*1c6fdbd8SKent Overstreet 		int i = ((int) (crc >> 56) ^ *data++) & 0xFF;
135*1c6fdbd8SKent Overstreet 		crc = crc_table[i] ^ (crc << 8);
136*1c6fdbd8SKent Overstreet 	}
137*1c6fdbd8SKent Overstreet 
138*1c6fdbd8SKent Overstreet 	return crc;
139*1c6fdbd8SKent Overstreet }
140*1c6fdbd8SKent Overstreet 
141*1c6fdbd8SKent Overstreet static u64 bch2_checksum_init(unsigned type)
142*1c6fdbd8SKent Overstreet {
143*1c6fdbd8SKent Overstreet 	switch (type) {
144*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
145*1c6fdbd8SKent Overstreet 		return 0;
146*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C_NONZERO:
147*1c6fdbd8SKent Overstreet 		return U32_MAX;
148*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64_NONZERO:
149*1c6fdbd8SKent Overstreet 		return U64_MAX;
150*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
151*1c6fdbd8SKent Overstreet 		return 0;
152*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64:
153*1c6fdbd8SKent Overstreet 		return 0;
154*1c6fdbd8SKent Overstreet 	default:
155*1c6fdbd8SKent Overstreet 		BUG();
156*1c6fdbd8SKent Overstreet 	}
157*1c6fdbd8SKent Overstreet }
158*1c6fdbd8SKent Overstreet 
159*1c6fdbd8SKent Overstreet static u64 bch2_checksum_final(unsigned type, u64 crc)
160*1c6fdbd8SKent Overstreet {
161*1c6fdbd8SKent Overstreet 	switch (type) {
162*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
163*1c6fdbd8SKent Overstreet 		return 0;
164*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C_NONZERO:
165*1c6fdbd8SKent Overstreet 		return crc ^ U32_MAX;
166*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64_NONZERO:
167*1c6fdbd8SKent Overstreet 		return crc ^ U64_MAX;
168*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
169*1c6fdbd8SKent Overstreet 		return crc;
170*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64:
171*1c6fdbd8SKent Overstreet 		return crc;
172*1c6fdbd8SKent Overstreet 	default:
173*1c6fdbd8SKent Overstreet 		BUG();
174*1c6fdbd8SKent Overstreet 	}
175*1c6fdbd8SKent Overstreet }
176*1c6fdbd8SKent Overstreet 
177*1c6fdbd8SKent Overstreet static u64 bch2_checksum_update(unsigned type, u64 crc, const void *data, size_t len)
178*1c6fdbd8SKent Overstreet {
179*1c6fdbd8SKent Overstreet 	switch (type) {
180*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
181*1c6fdbd8SKent Overstreet 		return 0;
182*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C_NONZERO:
183*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
184*1c6fdbd8SKent Overstreet 		return crc32c(crc, data, len);
185*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64_NONZERO:
186*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64:
187*1c6fdbd8SKent Overstreet 		return bch2_crc64_update(crc, data, len);
188*1c6fdbd8SKent Overstreet 	default:
189*1c6fdbd8SKent Overstreet 		BUG();
190*1c6fdbd8SKent Overstreet 	}
191*1c6fdbd8SKent Overstreet }
192*1c6fdbd8SKent Overstreet 
193*1c6fdbd8SKent Overstreet static inline void do_encrypt_sg(struct crypto_sync_skcipher *tfm,
194*1c6fdbd8SKent Overstreet 				 struct nonce nonce,
195*1c6fdbd8SKent Overstreet 				 struct scatterlist *sg, size_t len)
196*1c6fdbd8SKent Overstreet {
197*1c6fdbd8SKent Overstreet 	SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm);
198*1c6fdbd8SKent Overstreet 	int ret;
199*1c6fdbd8SKent Overstreet 
200*1c6fdbd8SKent Overstreet 	skcipher_request_set_sync_tfm(req, tfm);
201*1c6fdbd8SKent Overstreet 	skcipher_request_set_crypt(req, sg, sg, len, nonce.d);
202*1c6fdbd8SKent Overstreet 
203*1c6fdbd8SKent Overstreet 	ret = crypto_skcipher_encrypt(req);
204*1c6fdbd8SKent Overstreet 	BUG_ON(ret);
205*1c6fdbd8SKent Overstreet }
206*1c6fdbd8SKent Overstreet 
207*1c6fdbd8SKent Overstreet static inline void do_encrypt(struct crypto_sync_skcipher *tfm,
208*1c6fdbd8SKent Overstreet 			      struct nonce nonce,
209*1c6fdbd8SKent Overstreet 			      void *buf, size_t len)
210*1c6fdbd8SKent Overstreet {
211*1c6fdbd8SKent Overstreet 	struct scatterlist sg;
212*1c6fdbd8SKent Overstreet 
213*1c6fdbd8SKent Overstreet 	sg_init_one(&sg, buf, len);
214*1c6fdbd8SKent Overstreet 	do_encrypt_sg(tfm, nonce, &sg, len);
215*1c6fdbd8SKent Overstreet }
216*1c6fdbd8SKent Overstreet 
217*1c6fdbd8SKent Overstreet int bch2_chacha_encrypt_key(struct bch_key *key, struct nonce nonce,
218*1c6fdbd8SKent Overstreet 			    void *buf, size_t len)
219*1c6fdbd8SKent Overstreet {
220*1c6fdbd8SKent Overstreet 	struct crypto_sync_skcipher *chacha20 =
221*1c6fdbd8SKent Overstreet 		crypto_alloc_sync_skcipher("chacha20", 0, 0);
222*1c6fdbd8SKent Overstreet 	int ret;
223*1c6fdbd8SKent Overstreet 
224*1c6fdbd8SKent Overstreet 	if (!chacha20) {
225*1c6fdbd8SKent Overstreet 		pr_err("error requesting chacha20 module: %li", PTR_ERR(chacha20));
226*1c6fdbd8SKent Overstreet 		return PTR_ERR(chacha20);
227*1c6fdbd8SKent Overstreet 	}
228*1c6fdbd8SKent Overstreet 
229*1c6fdbd8SKent Overstreet 	ret = crypto_skcipher_setkey(&chacha20->base,
230*1c6fdbd8SKent Overstreet 				     (void *) key, sizeof(*key));
231*1c6fdbd8SKent Overstreet 	if (ret) {
232*1c6fdbd8SKent Overstreet 		pr_err("crypto_skcipher_setkey() error: %i", ret);
233*1c6fdbd8SKent Overstreet 		goto err;
234*1c6fdbd8SKent Overstreet 	}
235*1c6fdbd8SKent Overstreet 
236*1c6fdbd8SKent Overstreet 	do_encrypt(chacha20, nonce, buf, len);
237*1c6fdbd8SKent Overstreet err:
238*1c6fdbd8SKent Overstreet 	crypto_free_sync_skcipher(chacha20);
239*1c6fdbd8SKent Overstreet 	return ret;
240*1c6fdbd8SKent Overstreet }
241*1c6fdbd8SKent Overstreet 
242*1c6fdbd8SKent Overstreet static void gen_poly_key(struct bch_fs *c, struct shash_desc *desc,
243*1c6fdbd8SKent Overstreet 			 struct nonce nonce)
244*1c6fdbd8SKent Overstreet {
245*1c6fdbd8SKent Overstreet 	u8 key[POLY1305_KEY_SIZE];
246*1c6fdbd8SKent Overstreet 
247*1c6fdbd8SKent Overstreet 	nonce.d[3] ^= BCH_NONCE_POLY;
248*1c6fdbd8SKent Overstreet 
249*1c6fdbd8SKent Overstreet 	memset(key, 0, sizeof(key));
250*1c6fdbd8SKent Overstreet 	do_encrypt(c->chacha20, nonce, key, sizeof(key));
251*1c6fdbd8SKent Overstreet 
252*1c6fdbd8SKent Overstreet 	desc->tfm = c->poly1305;
253*1c6fdbd8SKent Overstreet 	crypto_shash_init(desc);
254*1c6fdbd8SKent Overstreet 	crypto_shash_update(desc, key, sizeof(key));
255*1c6fdbd8SKent Overstreet }
256*1c6fdbd8SKent Overstreet 
257*1c6fdbd8SKent Overstreet struct bch_csum bch2_checksum(struct bch_fs *c, unsigned type,
258*1c6fdbd8SKent Overstreet 			      struct nonce nonce, const void *data, size_t len)
259*1c6fdbd8SKent Overstreet {
260*1c6fdbd8SKent Overstreet 	switch (type) {
261*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
262*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C_NONZERO:
263*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64_NONZERO:
264*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
265*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64: {
266*1c6fdbd8SKent Overstreet 		u64 crc = bch2_checksum_init(type);
267*1c6fdbd8SKent Overstreet 
268*1c6fdbd8SKent Overstreet 		crc = bch2_checksum_update(type, crc, data, len);
269*1c6fdbd8SKent Overstreet 		crc = bch2_checksum_final(type, crc);
270*1c6fdbd8SKent Overstreet 
271*1c6fdbd8SKent Overstreet 		return (struct bch_csum) { .lo = cpu_to_le64(crc) };
272*1c6fdbd8SKent Overstreet 	}
273*1c6fdbd8SKent Overstreet 
274*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CHACHA20_POLY1305_80:
275*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CHACHA20_POLY1305_128: {
276*1c6fdbd8SKent Overstreet 		SHASH_DESC_ON_STACK(desc, c->poly1305);
277*1c6fdbd8SKent Overstreet 		u8 digest[POLY1305_DIGEST_SIZE];
278*1c6fdbd8SKent Overstreet 		struct bch_csum ret = { 0 };
279*1c6fdbd8SKent Overstreet 
280*1c6fdbd8SKent Overstreet 		gen_poly_key(c, desc, nonce);
281*1c6fdbd8SKent Overstreet 
282*1c6fdbd8SKent Overstreet 		crypto_shash_update(desc, data, len);
283*1c6fdbd8SKent Overstreet 		crypto_shash_final(desc, digest);
284*1c6fdbd8SKent Overstreet 
285*1c6fdbd8SKent Overstreet 		memcpy(&ret, digest, bch_crc_bytes[type]);
286*1c6fdbd8SKent Overstreet 		return ret;
287*1c6fdbd8SKent Overstreet 	}
288*1c6fdbd8SKent Overstreet 	default:
289*1c6fdbd8SKent Overstreet 		BUG();
290*1c6fdbd8SKent Overstreet 	}
291*1c6fdbd8SKent Overstreet }
292*1c6fdbd8SKent Overstreet 
293*1c6fdbd8SKent Overstreet void bch2_encrypt(struct bch_fs *c, unsigned type,
294*1c6fdbd8SKent Overstreet 		  struct nonce nonce, void *data, size_t len)
295*1c6fdbd8SKent Overstreet {
296*1c6fdbd8SKent Overstreet 	if (!bch2_csum_type_is_encryption(type))
297*1c6fdbd8SKent Overstreet 		return;
298*1c6fdbd8SKent Overstreet 
299*1c6fdbd8SKent Overstreet 	do_encrypt(c->chacha20, nonce, data, len);
300*1c6fdbd8SKent Overstreet }
301*1c6fdbd8SKent Overstreet 
302*1c6fdbd8SKent Overstreet static struct bch_csum __bch2_checksum_bio(struct bch_fs *c, unsigned type,
303*1c6fdbd8SKent Overstreet 					   struct nonce nonce, struct bio *bio,
304*1c6fdbd8SKent Overstreet 					   struct bvec_iter *iter)
305*1c6fdbd8SKent Overstreet {
306*1c6fdbd8SKent Overstreet 	struct bio_vec bv;
307*1c6fdbd8SKent Overstreet 
308*1c6fdbd8SKent Overstreet 	switch (type) {
309*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
310*1c6fdbd8SKent Overstreet 		return (struct bch_csum) { 0 };
311*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C_NONZERO:
312*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64_NONZERO:
313*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
314*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64: {
315*1c6fdbd8SKent Overstreet 		u64 crc = bch2_checksum_init(type);
316*1c6fdbd8SKent Overstreet 
317*1c6fdbd8SKent Overstreet #ifdef CONFIG_HIGHMEM
318*1c6fdbd8SKent Overstreet 		__bio_for_each_segment(bv, bio, *iter, *iter) {
319*1c6fdbd8SKent Overstreet 			void *p = kmap_atomic(bv.bv_page) + bv.bv_offset;
320*1c6fdbd8SKent Overstreet 			crc = bch2_checksum_update(type,
321*1c6fdbd8SKent Overstreet 				crc, p, bv.bv_len);
322*1c6fdbd8SKent Overstreet 			kunmap_atomic(p);
323*1c6fdbd8SKent Overstreet 		}
324*1c6fdbd8SKent Overstreet #else
325*1c6fdbd8SKent Overstreet 		__bio_for_each_contig_segment(bv, bio, *iter, *iter)
326*1c6fdbd8SKent Overstreet 			crc = bch2_checksum_update(type, crc,
327*1c6fdbd8SKent Overstreet 				page_address(bv.bv_page) + bv.bv_offset,
328*1c6fdbd8SKent Overstreet 				bv.bv_len);
329*1c6fdbd8SKent Overstreet #endif
330*1c6fdbd8SKent Overstreet 		crc = bch2_checksum_final(type, crc);
331*1c6fdbd8SKent Overstreet 		return (struct bch_csum) { .lo = cpu_to_le64(crc) };
332*1c6fdbd8SKent Overstreet 	}
333*1c6fdbd8SKent Overstreet 
334*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CHACHA20_POLY1305_80:
335*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CHACHA20_POLY1305_128: {
336*1c6fdbd8SKent Overstreet 		SHASH_DESC_ON_STACK(desc, c->poly1305);
337*1c6fdbd8SKent Overstreet 		u8 digest[POLY1305_DIGEST_SIZE];
338*1c6fdbd8SKent Overstreet 		struct bch_csum ret = { 0 };
339*1c6fdbd8SKent Overstreet 
340*1c6fdbd8SKent Overstreet 		gen_poly_key(c, desc, nonce);
341*1c6fdbd8SKent Overstreet 
342*1c6fdbd8SKent Overstreet #ifdef CONFIG_HIGHMEM
343*1c6fdbd8SKent Overstreet 		__bio_for_each_segment(bv, bio, *iter, *iter) {
344*1c6fdbd8SKent Overstreet 			void *p = kmap_atomic(bv.bv_page) + bv.bv_offset;
345*1c6fdbd8SKent Overstreet 
346*1c6fdbd8SKent Overstreet 			crypto_shash_update(desc, p, bv.bv_len);
347*1c6fdbd8SKent Overstreet 			kunmap_atomic(p);
348*1c6fdbd8SKent Overstreet 		}
349*1c6fdbd8SKent Overstreet #else
350*1c6fdbd8SKent Overstreet 		__bio_for_each_contig_segment(bv, bio, *iter, *iter)
351*1c6fdbd8SKent Overstreet 			crypto_shash_update(desc,
352*1c6fdbd8SKent Overstreet 				page_address(bv.bv_page) + bv.bv_offset,
353*1c6fdbd8SKent Overstreet 				bv.bv_len);
354*1c6fdbd8SKent Overstreet #endif
355*1c6fdbd8SKent Overstreet 		crypto_shash_final(desc, digest);
356*1c6fdbd8SKent Overstreet 
357*1c6fdbd8SKent Overstreet 		memcpy(&ret, digest, bch_crc_bytes[type]);
358*1c6fdbd8SKent Overstreet 		return ret;
359*1c6fdbd8SKent Overstreet 	}
360*1c6fdbd8SKent Overstreet 	default:
361*1c6fdbd8SKent Overstreet 		BUG();
362*1c6fdbd8SKent Overstreet 	}
363*1c6fdbd8SKent Overstreet }
364*1c6fdbd8SKent Overstreet 
365*1c6fdbd8SKent Overstreet struct bch_csum bch2_checksum_bio(struct bch_fs *c, unsigned type,
366*1c6fdbd8SKent Overstreet 				  struct nonce nonce, struct bio *bio)
367*1c6fdbd8SKent Overstreet {
368*1c6fdbd8SKent Overstreet 	struct bvec_iter iter = bio->bi_iter;
369*1c6fdbd8SKent Overstreet 
370*1c6fdbd8SKent Overstreet 	return __bch2_checksum_bio(c, type, nonce, bio, &iter);
371*1c6fdbd8SKent Overstreet }
372*1c6fdbd8SKent Overstreet 
373*1c6fdbd8SKent Overstreet void bch2_encrypt_bio(struct bch_fs *c, unsigned type,
374*1c6fdbd8SKent Overstreet 		      struct nonce nonce, struct bio *bio)
375*1c6fdbd8SKent Overstreet {
376*1c6fdbd8SKent Overstreet 	struct bio_vec bv;
377*1c6fdbd8SKent Overstreet 	struct bvec_iter iter;
378*1c6fdbd8SKent Overstreet 	struct scatterlist sgl[16], *sg = sgl;
379*1c6fdbd8SKent Overstreet 	size_t bytes = 0;
380*1c6fdbd8SKent Overstreet 
381*1c6fdbd8SKent Overstreet 	if (!bch2_csum_type_is_encryption(type))
382*1c6fdbd8SKent Overstreet 		return;
383*1c6fdbd8SKent Overstreet 
384*1c6fdbd8SKent Overstreet 	sg_init_table(sgl, ARRAY_SIZE(sgl));
385*1c6fdbd8SKent Overstreet 
386*1c6fdbd8SKent Overstreet 	bio_for_each_segment(bv, bio, iter) {
387*1c6fdbd8SKent Overstreet 		if (sg == sgl + ARRAY_SIZE(sgl)) {
388*1c6fdbd8SKent Overstreet 			sg_mark_end(sg - 1);
389*1c6fdbd8SKent Overstreet 			do_encrypt_sg(c->chacha20, nonce, sgl, bytes);
390*1c6fdbd8SKent Overstreet 
391*1c6fdbd8SKent Overstreet 			nonce = nonce_add(nonce, bytes);
392*1c6fdbd8SKent Overstreet 			bytes = 0;
393*1c6fdbd8SKent Overstreet 
394*1c6fdbd8SKent Overstreet 			sg_init_table(sgl, ARRAY_SIZE(sgl));
395*1c6fdbd8SKent Overstreet 			sg = sgl;
396*1c6fdbd8SKent Overstreet 		}
397*1c6fdbd8SKent Overstreet 
398*1c6fdbd8SKent Overstreet 		sg_set_page(sg++, bv.bv_page, bv.bv_len, bv.bv_offset);
399*1c6fdbd8SKent Overstreet 		bytes += bv.bv_len;
400*1c6fdbd8SKent Overstreet 	}
401*1c6fdbd8SKent Overstreet 
402*1c6fdbd8SKent Overstreet 	sg_mark_end(sg - 1);
403*1c6fdbd8SKent Overstreet 	do_encrypt_sg(c->chacha20, nonce, sgl, bytes);
404*1c6fdbd8SKent Overstreet }
405*1c6fdbd8SKent Overstreet 
406*1c6fdbd8SKent Overstreet static inline bool bch2_checksum_mergeable(unsigned type)
407*1c6fdbd8SKent Overstreet {
408*1c6fdbd8SKent Overstreet 
409*1c6fdbd8SKent Overstreet 	switch (type) {
410*1c6fdbd8SKent Overstreet 	case BCH_CSUM_NONE:
411*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC32C:
412*1c6fdbd8SKent Overstreet 	case BCH_CSUM_CRC64:
413*1c6fdbd8SKent Overstreet 		return true;
414*1c6fdbd8SKent Overstreet 	default:
415*1c6fdbd8SKent Overstreet 		return false;
416*1c6fdbd8SKent Overstreet 	}
417*1c6fdbd8SKent Overstreet }
418*1c6fdbd8SKent Overstreet 
419*1c6fdbd8SKent Overstreet static struct bch_csum bch2_checksum_merge(unsigned type,
420*1c6fdbd8SKent Overstreet 					   struct bch_csum a,
421*1c6fdbd8SKent Overstreet 					   struct bch_csum b, size_t b_len)
422*1c6fdbd8SKent Overstreet {
423*1c6fdbd8SKent Overstreet 	BUG_ON(!bch2_checksum_mergeable(type));
424*1c6fdbd8SKent Overstreet 
425*1c6fdbd8SKent Overstreet 	while (b_len) {
426*1c6fdbd8SKent Overstreet 		unsigned b = min_t(unsigned, b_len, PAGE_SIZE);
427*1c6fdbd8SKent Overstreet 
428*1c6fdbd8SKent Overstreet 		a.lo = bch2_checksum_update(type, a.lo,
429*1c6fdbd8SKent Overstreet 				page_address(ZERO_PAGE(0)), b);
430*1c6fdbd8SKent Overstreet 		b_len -= b;
431*1c6fdbd8SKent Overstreet 	}
432*1c6fdbd8SKent Overstreet 
433*1c6fdbd8SKent Overstreet 	a.lo ^= b.lo;
434*1c6fdbd8SKent Overstreet 	a.hi ^= b.hi;
435*1c6fdbd8SKent Overstreet 	return a;
436*1c6fdbd8SKent Overstreet }
437*1c6fdbd8SKent Overstreet 
438*1c6fdbd8SKent Overstreet int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio,
439*1c6fdbd8SKent Overstreet 			struct bversion version,
440*1c6fdbd8SKent Overstreet 			struct bch_extent_crc_unpacked crc_old,
441*1c6fdbd8SKent Overstreet 			struct bch_extent_crc_unpacked *crc_a,
442*1c6fdbd8SKent Overstreet 			struct bch_extent_crc_unpacked *crc_b,
443*1c6fdbd8SKent Overstreet 			unsigned len_a, unsigned len_b,
444*1c6fdbd8SKent Overstreet 			unsigned new_csum_type)
445*1c6fdbd8SKent Overstreet {
446*1c6fdbd8SKent Overstreet 	struct bvec_iter iter = bio->bi_iter;
447*1c6fdbd8SKent Overstreet 	struct nonce nonce = extent_nonce(version, crc_old);
448*1c6fdbd8SKent Overstreet 	struct bch_csum merged = { 0 };
449*1c6fdbd8SKent Overstreet 	struct crc_split {
450*1c6fdbd8SKent Overstreet 		struct bch_extent_crc_unpacked	*crc;
451*1c6fdbd8SKent Overstreet 		unsigned			len;
452*1c6fdbd8SKent Overstreet 		unsigned			csum_type;
453*1c6fdbd8SKent Overstreet 		struct bch_csum			csum;
454*1c6fdbd8SKent Overstreet 	} splits[3] = {
455*1c6fdbd8SKent Overstreet 		{ crc_a, len_a, new_csum_type },
456*1c6fdbd8SKent Overstreet 		{ crc_b, len_b, new_csum_type },
457*1c6fdbd8SKent Overstreet 		{ NULL,	 bio_sectors(bio) - len_a - len_b, new_csum_type },
458*1c6fdbd8SKent Overstreet 	}, *i;
459*1c6fdbd8SKent Overstreet 	bool mergeable = crc_old.csum_type == new_csum_type &&
460*1c6fdbd8SKent Overstreet 		bch2_checksum_mergeable(new_csum_type);
461*1c6fdbd8SKent Overstreet 	unsigned crc_nonce = crc_old.nonce;
462*1c6fdbd8SKent Overstreet 
463*1c6fdbd8SKent Overstreet 	BUG_ON(len_a + len_b > bio_sectors(bio));
464*1c6fdbd8SKent Overstreet 	BUG_ON(crc_old.uncompressed_size != bio_sectors(bio));
465*1c6fdbd8SKent Overstreet 	BUG_ON(crc_old.compression_type);
466*1c6fdbd8SKent Overstreet 	BUG_ON(bch2_csum_type_is_encryption(crc_old.csum_type) !=
467*1c6fdbd8SKent Overstreet 	       bch2_csum_type_is_encryption(new_csum_type));
468*1c6fdbd8SKent Overstreet 
469*1c6fdbd8SKent Overstreet 	for (i = splits; i < splits + ARRAY_SIZE(splits); i++) {
470*1c6fdbd8SKent Overstreet 		iter.bi_size = i->len << 9;
471*1c6fdbd8SKent Overstreet 		if (mergeable || i->crc)
472*1c6fdbd8SKent Overstreet 			i->csum = __bch2_checksum_bio(c, i->csum_type,
473*1c6fdbd8SKent Overstreet 						      nonce, bio, &iter);
474*1c6fdbd8SKent Overstreet 		else
475*1c6fdbd8SKent Overstreet 			bio_advance_iter(bio, &iter, i->len << 9);
476*1c6fdbd8SKent Overstreet 		nonce = nonce_add(nonce, i->len << 9);
477*1c6fdbd8SKent Overstreet 	}
478*1c6fdbd8SKent Overstreet 
479*1c6fdbd8SKent Overstreet 	if (mergeable)
480*1c6fdbd8SKent Overstreet 		for (i = splits; i < splits + ARRAY_SIZE(splits); i++)
481*1c6fdbd8SKent Overstreet 			merged = bch2_checksum_merge(new_csum_type, merged,
482*1c6fdbd8SKent Overstreet 						     i->csum, i->len << 9);
483*1c6fdbd8SKent Overstreet 	else
484*1c6fdbd8SKent Overstreet 		merged = bch2_checksum_bio(c, crc_old.csum_type,
485*1c6fdbd8SKent Overstreet 				extent_nonce(version, crc_old), bio);
486*1c6fdbd8SKent Overstreet 
487*1c6fdbd8SKent Overstreet 	if (bch2_crc_cmp(merged, crc_old.csum))
488*1c6fdbd8SKent Overstreet 		return -EIO;
489*1c6fdbd8SKent Overstreet 
490*1c6fdbd8SKent Overstreet 	for (i = splits; i < splits + ARRAY_SIZE(splits); i++) {
491*1c6fdbd8SKent Overstreet 		if (i->crc)
492*1c6fdbd8SKent Overstreet 			*i->crc = (struct bch_extent_crc_unpacked) {
493*1c6fdbd8SKent Overstreet 				.csum_type		= i->csum_type,
494*1c6fdbd8SKent Overstreet 				.compressed_size	= i->len,
495*1c6fdbd8SKent Overstreet 				.uncompressed_size	= i->len,
496*1c6fdbd8SKent Overstreet 				.offset			= 0,
497*1c6fdbd8SKent Overstreet 				.live_size		= i->len,
498*1c6fdbd8SKent Overstreet 				.nonce			= crc_nonce,
499*1c6fdbd8SKent Overstreet 				.csum			= i->csum,
500*1c6fdbd8SKent Overstreet 			};
501*1c6fdbd8SKent Overstreet 
502*1c6fdbd8SKent Overstreet 		if (bch2_csum_type_is_encryption(new_csum_type))
503*1c6fdbd8SKent Overstreet 			crc_nonce += i->len;
504*1c6fdbd8SKent Overstreet 	}
505*1c6fdbd8SKent Overstreet 
506*1c6fdbd8SKent Overstreet 	return 0;
507*1c6fdbd8SKent Overstreet }
508*1c6fdbd8SKent Overstreet 
509*1c6fdbd8SKent Overstreet #ifdef __KERNEL__
510*1c6fdbd8SKent Overstreet int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
511*1c6fdbd8SKent Overstreet {
512*1c6fdbd8SKent Overstreet 	char key_description[60];
513*1c6fdbd8SKent Overstreet 	struct key *keyring_key;
514*1c6fdbd8SKent Overstreet 	const struct user_key_payload *ukp;
515*1c6fdbd8SKent Overstreet 	int ret;
516*1c6fdbd8SKent Overstreet 
517*1c6fdbd8SKent Overstreet 	snprintf(key_description, sizeof(key_description),
518*1c6fdbd8SKent Overstreet 		 "bcachefs:%pUb", &sb->user_uuid);
519*1c6fdbd8SKent Overstreet 
520*1c6fdbd8SKent Overstreet 	keyring_key = request_key(&key_type_logon, key_description, NULL);
521*1c6fdbd8SKent Overstreet 	if (IS_ERR(keyring_key))
522*1c6fdbd8SKent Overstreet 		return PTR_ERR(keyring_key);
523*1c6fdbd8SKent Overstreet 
524*1c6fdbd8SKent Overstreet 	down_read(&keyring_key->sem);
525*1c6fdbd8SKent Overstreet 	ukp = dereference_key_locked(keyring_key);
526*1c6fdbd8SKent Overstreet 	if (ukp->datalen == sizeof(*key)) {
527*1c6fdbd8SKent Overstreet 		memcpy(key, ukp->data, ukp->datalen);
528*1c6fdbd8SKent Overstreet 		ret = 0;
529*1c6fdbd8SKent Overstreet 	} else {
530*1c6fdbd8SKent Overstreet 		ret = -EINVAL;
531*1c6fdbd8SKent Overstreet 	}
532*1c6fdbd8SKent Overstreet 	up_read(&keyring_key->sem);
533*1c6fdbd8SKent Overstreet 	key_put(keyring_key);
534*1c6fdbd8SKent Overstreet 
535*1c6fdbd8SKent Overstreet 	return ret;
536*1c6fdbd8SKent Overstreet }
537*1c6fdbd8SKent Overstreet #else
538*1c6fdbd8SKent Overstreet #include <keyutils.h>
539*1c6fdbd8SKent Overstreet #include <uuid/uuid.h>
540*1c6fdbd8SKent Overstreet 
541*1c6fdbd8SKent Overstreet int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
542*1c6fdbd8SKent Overstreet {
543*1c6fdbd8SKent Overstreet 	key_serial_t key_id;
544*1c6fdbd8SKent Overstreet 	char key_description[60];
545*1c6fdbd8SKent Overstreet 	char uuid[40];
546*1c6fdbd8SKent Overstreet 
547*1c6fdbd8SKent Overstreet 	uuid_unparse_lower(sb->user_uuid.b, uuid);
548*1c6fdbd8SKent Overstreet 	sprintf(key_description, "bcachefs:%s", uuid);
549*1c6fdbd8SKent Overstreet 
550*1c6fdbd8SKent Overstreet 	key_id = request_key("user", key_description, NULL,
551*1c6fdbd8SKent Overstreet 			     KEY_SPEC_USER_KEYRING);
552*1c6fdbd8SKent Overstreet 	if (key_id < 0)
553*1c6fdbd8SKent Overstreet 		return -errno;
554*1c6fdbd8SKent Overstreet 
555*1c6fdbd8SKent Overstreet 	if (keyctl_read(key_id, (void *) key, sizeof(*key)) != sizeof(*key))
556*1c6fdbd8SKent Overstreet 		return -1;
557*1c6fdbd8SKent Overstreet 
558*1c6fdbd8SKent Overstreet 	return 0;
559*1c6fdbd8SKent Overstreet }
560*1c6fdbd8SKent Overstreet #endif
561*1c6fdbd8SKent Overstreet 
562*1c6fdbd8SKent Overstreet int bch2_decrypt_sb_key(struct bch_fs *c,
563*1c6fdbd8SKent Overstreet 			struct bch_sb_field_crypt *crypt,
564*1c6fdbd8SKent Overstreet 			struct bch_key *key)
565*1c6fdbd8SKent Overstreet {
566*1c6fdbd8SKent Overstreet 	struct bch_encrypted_key sb_key = crypt->key;
567*1c6fdbd8SKent Overstreet 	struct bch_key user_key;
568*1c6fdbd8SKent Overstreet 	int ret = 0;
569*1c6fdbd8SKent Overstreet 
570*1c6fdbd8SKent Overstreet 	/* is key encrypted? */
571*1c6fdbd8SKent Overstreet 	if (!bch2_key_is_encrypted(&sb_key))
572*1c6fdbd8SKent Overstreet 		goto out;
573*1c6fdbd8SKent Overstreet 
574*1c6fdbd8SKent Overstreet 	ret = bch2_request_key(c->disk_sb.sb, &user_key);
575*1c6fdbd8SKent Overstreet 	if (ret) {
576*1c6fdbd8SKent Overstreet 		bch_err(c, "error requesting encryption key: %i", ret);
577*1c6fdbd8SKent Overstreet 		goto err;
578*1c6fdbd8SKent Overstreet 	}
579*1c6fdbd8SKent Overstreet 
580*1c6fdbd8SKent Overstreet 	/* decrypt real key: */
581*1c6fdbd8SKent Overstreet 	ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
582*1c6fdbd8SKent Overstreet 			     &sb_key, sizeof(sb_key));
583*1c6fdbd8SKent Overstreet 	if (ret)
584*1c6fdbd8SKent Overstreet 		goto err;
585*1c6fdbd8SKent Overstreet 
586*1c6fdbd8SKent Overstreet 	if (bch2_key_is_encrypted(&sb_key)) {
587*1c6fdbd8SKent Overstreet 		bch_err(c, "incorrect encryption key");
588*1c6fdbd8SKent Overstreet 		ret = -EINVAL;
589*1c6fdbd8SKent Overstreet 		goto err;
590*1c6fdbd8SKent Overstreet 	}
591*1c6fdbd8SKent Overstreet out:
592*1c6fdbd8SKent Overstreet 	*key = sb_key.key;
593*1c6fdbd8SKent Overstreet err:
594*1c6fdbd8SKent Overstreet 	memzero_explicit(&sb_key, sizeof(sb_key));
595*1c6fdbd8SKent Overstreet 	memzero_explicit(&user_key, sizeof(user_key));
596*1c6fdbd8SKent Overstreet 	return ret;
597*1c6fdbd8SKent Overstreet }
598*1c6fdbd8SKent Overstreet 
599*1c6fdbd8SKent Overstreet static int bch2_alloc_ciphers(struct bch_fs *c)
600*1c6fdbd8SKent Overstreet {
601*1c6fdbd8SKent Overstreet 	if (!c->chacha20)
602*1c6fdbd8SKent Overstreet 		c->chacha20 = crypto_alloc_sync_skcipher("chacha20", 0, 0);
603*1c6fdbd8SKent Overstreet 	if (IS_ERR(c->chacha20)) {
604*1c6fdbd8SKent Overstreet 		bch_err(c, "error requesting chacha20 module: %li",
605*1c6fdbd8SKent Overstreet 			PTR_ERR(c->chacha20));
606*1c6fdbd8SKent Overstreet 		return PTR_ERR(c->chacha20);
607*1c6fdbd8SKent Overstreet 	}
608*1c6fdbd8SKent Overstreet 
609*1c6fdbd8SKent Overstreet 	if (!c->poly1305)
610*1c6fdbd8SKent Overstreet 		c->poly1305 = crypto_alloc_shash("poly1305", 0, 0);
611*1c6fdbd8SKent Overstreet 	if (IS_ERR(c->poly1305)) {
612*1c6fdbd8SKent Overstreet 		bch_err(c, "error requesting poly1305 module: %li",
613*1c6fdbd8SKent Overstreet 			PTR_ERR(c->poly1305));
614*1c6fdbd8SKent Overstreet 		return PTR_ERR(c->poly1305);
615*1c6fdbd8SKent Overstreet 	}
616*1c6fdbd8SKent Overstreet 
617*1c6fdbd8SKent Overstreet 	return 0;
618*1c6fdbd8SKent Overstreet }
619*1c6fdbd8SKent Overstreet 
620*1c6fdbd8SKent Overstreet int bch2_disable_encryption(struct bch_fs *c)
621*1c6fdbd8SKent Overstreet {
622*1c6fdbd8SKent Overstreet 	struct bch_sb_field_crypt *crypt;
623*1c6fdbd8SKent Overstreet 	struct bch_key key;
624*1c6fdbd8SKent Overstreet 	int ret = -EINVAL;
625*1c6fdbd8SKent Overstreet 
626*1c6fdbd8SKent Overstreet 	mutex_lock(&c->sb_lock);
627*1c6fdbd8SKent Overstreet 
628*1c6fdbd8SKent Overstreet 	crypt = bch2_sb_get_crypt(c->disk_sb.sb);
629*1c6fdbd8SKent Overstreet 	if (!crypt)
630*1c6fdbd8SKent Overstreet 		goto out;
631*1c6fdbd8SKent Overstreet 
632*1c6fdbd8SKent Overstreet 	/* is key encrypted? */
633*1c6fdbd8SKent Overstreet 	ret = 0;
634*1c6fdbd8SKent Overstreet 	if (bch2_key_is_encrypted(&crypt->key))
635*1c6fdbd8SKent Overstreet 		goto out;
636*1c6fdbd8SKent Overstreet 
637*1c6fdbd8SKent Overstreet 	ret = bch2_decrypt_sb_key(c, crypt, &key);
638*1c6fdbd8SKent Overstreet 	if (ret)
639*1c6fdbd8SKent Overstreet 		goto out;
640*1c6fdbd8SKent Overstreet 
641*1c6fdbd8SKent Overstreet 	crypt->key.magic	= BCH_KEY_MAGIC;
642*1c6fdbd8SKent Overstreet 	crypt->key.key		= key;
643*1c6fdbd8SKent Overstreet 
644*1c6fdbd8SKent Overstreet 	SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 0);
645*1c6fdbd8SKent Overstreet 	bch2_write_super(c);
646*1c6fdbd8SKent Overstreet out:
647*1c6fdbd8SKent Overstreet 	mutex_unlock(&c->sb_lock);
648*1c6fdbd8SKent Overstreet 
649*1c6fdbd8SKent Overstreet 	return ret;
650*1c6fdbd8SKent Overstreet }
651*1c6fdbd8SKent Overstreet 
652*1c6fdbd8SKent Overstreet int bch2_enable_encryption(struct bch_fs *c, bool keyed)
653*1c6fdbd8SKent Overstreet {
654*1c6fdbd8SKent Overstreet 	struct bch_encrypted_key key;
655*1c6fdbd8SKent Overstreet 	struct bch_key user_key;
656*1c6fdbd8SKent Overstreet 	struct bch_sb_field_crypt *crypt;
657*1c6fdbd8SKent Overstreet 	int ret = -EINVAL;
658*1c6fdbd8SKent Overstreet 
659*1c6fdbd8SKent Overstreet 	mutex_lock(&c->sb_lock);
660*1c6fdbd8SKent Overstreet 
661*1c6fdbd8SKent Overstreet 	/* Do we already have an encryption key? */
662*1c6fdbd8SKent Overstreet 	if (bch2_sb_get_crypt(c->disk_sb.sb))
663*1c6fdbd8SKent Overstreet 		goto err;
664*1c6fdbd8SKent Overstreet 
665*1c6fdbd8SKent Overstreet 	ret = bch2_alloc_ciphers(c);
666*1c6fdbd8SKent Overstreet 	if (ret)
667*1c6fdbd8SKent Overstreet 		goto err;
668*1c6fdbd8SKent Overstreet 
669*1c6fdbd8SKent Overstreet 	key.magic = BCH_KEY_MAGIC;
670*1c6fdbd8SKent Overstreet 	get_random_bytes(&key.key, sizeof(key.key));
671*1c6fdbd8SKent Overstreet 
672*1c6fdbd8SKent Overstreet 	if (keyed) {
673*1c6fdbd8SKent Overstreet 		ret = bch2_request_key(c->disk_sb.sb, &user_key);
674*1c6fdbd8SKent Overstreet 		if (ret) {
675*1c6fdbd8SKent Overstreet 			bch_err(c, "error requesting encryption key: %i", ret);
676*1c6fdbd8SKent Overstreet 			goto err;
677*1c6fdbd8SKent Overstreet 		}
678*1c6fdbd8SKent Overstreet 
679*1c6fdbd8SKent Overstreet 		ret = bch2_chacha_encrypt_key(&user_key, bch2_sb_key_nonce(c),
680*1c6fdbd8SKent Overstreet 					      &key, sizeof(key));
681*1c6fdbd8SKent Overstreet 		if (ret)
682*1c6fdbd8SKent Overstreet 			goto err;
683*1c6fdbd8SKent Overstreet 	}
684*1c6fdbd8SKent Overstreet 
685*1c6fdbd8SKent Overstreet 	ret = crypto_skcipher_setkey(&c->chacha20->base,
686*1c6fdbd8SKent Overstreet 			(void *) &key.key, sizeof(key.key));
687*1c6fdbd8SKent Overstreet 	if (ret)
688*1c6fdbd8SKent Overstreet 		goto err;
689*1c6fdbd8SKent Overstreet 
690*1c6fdbd8SKent Overstreet 	crypt = bch2_sb_resize_crypt(&c->disk_sb, sizeof(*crypt) / sizeof(u64));
691*1c6fdbd8SKent Overstreet 	if (!crypt) {
692*1c6fdbd8SKent Overstreet 		ret = -ENOMEM; /* XXX this technically could be -ENOSPC */
693*1c6fdbd8SKent Overstreet 		goto err;
694*1c6fdbd8SKent Overstreet 	}
695*1c6fdbd8SKent Overstreet 
696*1c6fdbd8SKent Overstreet 	crypt->key = key;
697*1c6fdbd8SKent Overstreet 
698*1c6fdbd8SKent Overstreet 	/* write superblock */
699*1c6fdbd8SKent Overstreet 	SET_BCH_SB_ENCRYPTION_TYPE(c->disk_sb.sb, 1);
700*1c6fdbd8SKent Overstreet 	bch2_write_super(c);
701*1c6fdbd8SKent Overstreet err:
702*1c6fdbd8SKent Overstreet 	mutex_unlock(&c->sb_lock);
703*1c6fdbd8SKent Overstreet 	memzero_explicit(&user_key, sizeof(user_key));
704*1c6fdbd8SKent Overstreet 	memzero_explicit(&key, sizeof(key));
705*1c6fdbd8SKent Overstreet 	return ret;
706*1c6fdbd8SKent Overstreet }
707*1c6fdbd8SKent Overstreet 
708*1c6fdbd8SKent Overstreet void bch2_fs_encryption_exit(struct bch_fs *c)
709*1c6fdbd8SKent Overstreet {
710*1c6fdbd8SKent Overstreet 	if (!IS_ERR_OR_NULL(c->poly1305))
711*1c6fdbd8SKent Overstreet 		crypto_free_shash(c->poly1305);
712*1c6fdbd8SKent Overstreet 	if (!IS_ERR_OR_NULL(c->chacha20))
713*1c6fdbd8SKent Overstreet 		crypto_free_sync_skcipher(c->chacha20);
714*1c6fdbd8SKent Overstreet 	if (!IS_ERR_OR_NULL(c->sha256))
715*1c6fdbd8SKent Overstreet 		crypto_free_shash(c->sha256);
716*1c6fdbd8SKent Overstreet }
717*1c6fdbd8SKent Overstreet 
718*1c6fdbd8SKent Overstreet int bch2_fs_encryption_init(struct bch_fs *c)
719*1c6fdbd8SKent Overstreet {
720*1c6fdbd8SKent Overstreet 	struct bch_sb_field_crypt *crypt;
721*1c6fdbd8SKent Overstreet 	struct bch_key key;
722*1c6fdbd8SKent Overstreet 	int ret = 0;
723*1c6fdbd8SKent Overstreet 
724*1c6fdbd8SKent Overstreet 	pr_verbose_init(c->opts, "");
725*1c6fdbd8SKent Overstreet 
726*1c6fdbd8SKent Overstreet 	c->sha256 = crypto_alloc_shash("sha256", 0, 0);
727*1c6fdbd8SKent Overstreet 	if (IS_ERR(c->sha256)) {
728*1c6fdbd8SKent Overstreet 		bch_err(c, "error requesting sha256 module");
729*1c6fdbd8SKent Overstreet 		ret = PTR_ERR(c->sha256);
730*1c6fdbd8SKent Overstreet 		goto out;
731*1c6fdbd8SKent Overstreet 	}
732*1c6fdbd8SKent Overstreet 
733*1c6fdbd8SKent Overstreet 	crypt = bch2_sb_get_crypt(c->disk_sb.sb);
734*1c6fdbd8SKent Overstreet 	if (!crypt)
735*1c6fdbd8SKent Overstreet 		goto out;
736*1c6fdbd8SKent Overstreet 
737*1c6fdbd8SKent Overstreet 	ret = bch2_alloc_ciphers(c);
738*1c6fdbd8SKent Overstreet 	if (ret)
739*1c6fdbd8SKent Overstreet 		goto out;
740*1c6fdbd8SKent Overstreet 
741*1c6fdbd8SKent Overstreet 	ret = bch2_decrypt_sb_key(c, crypt, &key);
742*1c6fdbd8SKent Overstreet 	if (ret)
743*1c6fdbd8SKent Overstreet 		goto out;
744*1c6fdbd8SKent Overstreet 
745*1c6fdbd8SKent Overstreet 	ret = crypto_skcipher_setkey(&c->chacha20->base,
746*1c6fdbd8SKent Overstreet 			(void *) &key.key, sizeof(key.key));
747*1c6fdbd8SKent Overstreet 	if (ret)
748*1c6fdbd8SKent Overstreet 		goto out;
749*1c6fdbd8SKent Overstreet out:
750*1c6fdbd8SKent Overstreet 	memzero_explicit(&key, sizeof(key));
751*1c6fdbd8SKent Overstreet 	pr_verbose_init(c->opts, "ret %i", ret);
752*1c6fdbd8SKent Overstreet 	return ret;
753*1c6fdbd8SKent Overstreet }
754