CCM

**Counter/CBC MAC** (נקרא גם CCMP) הוא מצב הפעלה גנרי של צופן בלוקים להצפנה מאומתת שמספק סודיות והבטחת שלמות. פותח ב-2003 על ידי דאג ווייטינג מחברת Hifn, רוס האוסלי לשעבר מ-RSA וניילס פרגוסון ממיקרוסופט כמועמד לתקן הצפנה מאומתת של NIST. האלגוריתם שייך לקטגוריה AEAD (הצפנה מאומתת עם מידע נלווה), בבסיסו שני פרימיטיבים קריפטוגרפיים נפרדים והוא פועל בשתי ריצות; בריצה ראשונה המסר מוצפן באמצעות צופן בלוקים סימטרי במצב מונה המשלב הצפנה של בלוקים מרובים בתוספת אינדקס הבלוק. בריצה השנייה המסר מאומת על ידי קוד אימות מסרים CBC-MAC, המייצר תג אימות של המסר המוצפן יחד עם מידע נלווה אם ישנו. קיימת הוכחה שמבנה זה בטוח בהנחה שצופן הבלוקים שביסודו בטוח, כמו כן אפשר להשיג בדרך זו סודיות בלבד ו/או הבטחת שלמות ואימות ללא סודיות, אם דרוש. CCM אינו תומך און ליין ואינו מתאים להזרמת מדיה. CCM נתמך בתקן SP 800-38C, נמצא בשימוש IPSec הוצע ב- עבור TLS והוא מצב הפעלה מנדטורי של IEEE 802.11i בתקן 802.15.4-2001 כחלק מפרוטוקול WPA2 וכן בשינויים קלים בפרוטוקול ZigBee ובפרוטוקול האבטחה של בלוטות'.

## הצפנה מאומתת

הצורך בהצפנה מאומתת עולה בשל העובדה שצופן בלוקים מעצם ההגדרה מבטיח רק סודיות והניסיונות לשלב אימות בשיטות אד הוק הולידו מערכות לקויות. הצפנה מאומתת נותנת מענה לסודיות המידע ובמקביל גם לשלמותו באופן בטוח. מיהיר בלייר ופיליפ רוגווי העלו לראשונה את מושג 'הרכבה גנרית' של הצפנה עם אימות באופן שצופן הבלוקים שבשימוש מופרד מהאימות והראו שלוש דרכים בסיסיות בטוחות. הנחת העבודה היא שהשולח והמקבל משתפים ביניהם מראש מפתח הצפנה סודי, המצפין משתמש במפתח שברשותו כדי להצפין את המידע באמצעות צופן סימטרי ולייצר 'תג אימות' באמצעות קוד אימות המסרים, אותו יחד עם המסר המוצפן הוא שולח למקבל. המקבל מצידו משתמש במפתח הסודי שברשותו כדי לפענח את המידע ובאותה מידה לבדוק באמצעות פונקציית האימות את התג שקיבל כדי לוודא את שלמות המידע שקיבל. תג האימות משמש להוכחה שהמידע לא זויף כי מעצם ההגדרה בלתי אפשרי ליריב בעל עוצמת חישוב סבירה לזייף טקסט-מוצפן ותג אימות מתאים ללא ידיעת המפתח הסודי.

AEAD – **הצפנה מאומתת עם מידע נלווה** נולדה עקב צורך מעשי. כאשר משתמשים מתקשרים ביניהם לצורך העברת חומר סודי, חלק מסוים מהמידע המועבר ברשת גלוי כמו קובץ כותר (header) וכן פרטים כמו כתובת IP וכדומה. המידע הגלוי משמש את השרתים ומסיבה זו חייב להיות גלוי אך יש צורך להגן עליו מפני שינוי זדוני שעלול לסכן את המידע המוצפן. הרעיון הוא שמערכת ההצפנה במחיר מועט תוכל להבטיח גם את שלמות המידע הגלוי המשויך למסר המוצפן.

## תיאור האלגוריתם
400px|ממוזער|שמאל|תיאור CCM
עבור CCM גנרי ישנם שני פרמטרים לקבוע. הראשון הוא M שמגדיר את אורך שדה האימות. ערכו של M הוא מעין שקלול בין התרחבות המסר המוצפן לבין הסיכויים שמתקיף יצליח לזייפו בלי שהמשתמשים יבחינו בכך. ערכים אפשריים הם 4,6,8,10,12,14,16 בתים. הבחירה השנייה היא L שמגדיר את מספר הבתים המוקצה לשדה אורך המידע המיועד להצפנה. ערך זה הוא פשרה בין אורך מקסימלי של מידע שאפשר להצפין לבין אורך וקטור האתחול ערכו של L לא יכול להיות קבוע כי הוא תלוי ביישום. ערכים אפשריים הם בין שני בתים לשמונה בתים. הערך L=1 שמור. הטבלה הבאה מסכמת את הפרמטרים הבסיסים של CCM:




את שני הפרמטרים מקודדים בבית הראשון (לפי הפירוט להלן). וקטור האתחול N צריך להיות בגודל 15-L בתים וחייב להיות חד-פעמי. אין להצפין שני מסרים עם אותו וקטור אתחול (אם המפתח לא הוחלף) כי מצב כזה ממוטט את ביטחון המערכת כליל. אורך המסר המקסימלי שניתן להצפנה מאומתת יהיה עד 2^{8L} בתים. מגבלה זו נועדה להבטיח שאפשר יהיה לקודד את אורך המסר בשדה באורך L בתים. אורך המידע הנלווה יהיה בין 0 ל-2^{64} בתים. המידע הנלווה מאומת אך לא מוצפן ואינו חובה. כדי לשלוח מסר מוצפן ומאומת השולח צריך תחילה לספק את הנתונים הבאים:
* מפתח הצפנה K המתאים לצופן הבלוקים שנבחר לשמש כבסיס למערכת (לדוגמה צופן AES עם מפתח באורך 128 סיביות).
* ערך חד-פעמי המסומן כאן N באורך 15-L בתים. חשוב ש-N יהיה ייחודי עבור כל מפתח נתון ואין לחזור ולהצפין שני מסרים שונים עם אותו מפתח K ואותו N אחרת ביטחון המערכת נהרס לחלוטין.
* מסר P המכיל l(p) בתים כאשר 0\le l(p). מגבלת האורך מבטיחה שניתן יהיה לקודד את ערך l(p) בתוך שדה באורך L בתים.
* מידע נלווה A אם ישנו, באורך l(a) בתים כאשר 0\le l(a). המידע הנלווה מאומת אך נותר גלוי והוא אינו חלק מפלט CCM. אפשר להשתמש באלגוריתם כדי לאמת חבילות מידע גלוי כמו כותרים המכילים מידע כללי בקשר למידע המוצפן העובר ברשת. מידע נלווה אינו חובה ואפשר לספק מחרוזת ריקה באורך אפס.

הטבלה הבאה מסכמת את הנתונים שהשולח צריך להכין:



המידע הנלווה יחד עם וקטור האתחול מחולקים ל-r+1 בלוקים B_0,B_1,...,B_r (כמפורט להלן) וכן A או P צריכים להיות כפולות של 8 סיביות ויכולים להיות ריקים מה שמרחיב את האופציות, למשל אם P ריק האלגוריתם מספק אימות בלבד של המסר הגלוי A. האלגוריתם מייצר בלוקים המשמשים כמונה אותם ניתן לחשב מראש עבור מפתח נתון כדי להפחית בעבודה אם צריך לאמת מספר רב של מסרים. הביטוי Y_0=E_K(B_0) מתייחס להצפנת הבלוק B_0 באמצעות צופן הבלוקים E (כמו AES) עם המפתח K כשהתוצאה ב-Y_0. הפונקציה \text{MSB}_{Tlen}(Y_r) מחזירה את Tlen הסיביות המשמעותיות ביותר של Y_r באופן דומה מייצגת הפונקציה LSB את הסיביות הפחות משמעותיות. והסימן \oplus הוא הפעולה XOR.

### הצפנה ואימות
**קלט:** מפתח הצפנה סודי משותף K, אורך תג אימות הרצוי \mathit{Tlen}, וקטור אתחול N, טקסט מקור P באורך \mathit{Plen} סיביות ומידע נלווה A כשהם מפורמטים לפי הוראות התקן להלן.

**פלט:** טקסט מוצפן C.
#**פורמט**. מחלקים את הקלט N,A,P לבלוקים B_0,B_1,...,B_r בגודל 128 סיביות כל אחד, לפי ההנחיות להלן.
#**וקטור אתחול**. מצפינים את הבלוק הראשון (שהוא וקטור האתחול): Y_0=E_K(B_0).
#**חישוב תג אימות**.
#:עבור i=1 עד r מבצעים:
#::Y_i=E_K(B_i\oplus Y_{i-1}).
#:תג האימות הוא T=\text{MSB}_{Tlen}(Y_r).
#**חישוב המונה**. מכינים m+1 מונים: Ctr_0,Ctr_1,...,Ctr_m כאשר m=\left \lceil \mathit{Plen}/128\right \rceil לפי ההוראות להלן.
#**הצפנת המונה**.
#:עבור j=0 עד m מבצעים:
#::S_j=E_K(Ctr_j)
#:התוצאה היא m+1 בלוקים. הבלוק S_0 המשמש להצפנת תג האימות והבלוקים: S=(S_1 \ \| \ S_2 \ \| \ \cdots \ \| \ S_m) המשמשים להצפנת המסר.
#**הצפנת המסר**.
#:עבור i=1 עד m מבצעים: C_i=(P_i\oplus S_i). אם הבלוק האחרון אינו מלא, מצבעים חיתוך של בלוק המונה האחרון לפי הצורך, כך שמתקבל C=P\oplus\text{MSB}_{\text{Tlen}}(S).
#**הצפנת תג האימות**. מצפינים את התג T=T\oplus \text{MSB}_{Tlen}(S_0).
#**פלט**. התוצאה היא C \ \| \ T.

### פענוח ואימות
**קלט:** מפתח הצפנה סודי משותף K, אורך תג האימות \mathit{Tlen}, וקטור אתחול N, מידע נלווה A וטקסט מוצפן C באורך \mathit{Clen} סיביות.

**פלט:** P או סמל מיוחד המייצג כישלון **INVALID**.
#מוודים ש-\mathit{Clen}\le \mathit{Tlen} אם לא מחזירים **INVALID**.
#מייצרים את המונה. Ctr_0,Ctr_1,...,Ctr_m כאשר m=\left \lceil (Clen-Tlen)/128\right \rceil.
#מצפינים את המונה. עבור j=0 עד m מבצעים: S_j=E_K(Ctr_j).
#הבלוקים של המונה הם: S=S_0 \ \| \ S_1 \ \| \ S_2 \ \| \ \cdots \ \| \ S_m.
#מפענחים את הטקסט המוצפן. P=\text{MSB}_{\mathit{Clen}-\mathit{Tlen}}(C)\oplus \text{MSB}_{Clen-Tlen}(S).
#מחשבים את תג האימות T=\text{LSB}_{Tlen}(C)\oplus \text{MSB}_{Tlen}(S_0).
#מוודים ש-N,A,P מתאימים להוראות התקן ומחלקים אותם לבלוקים B_0,B_1,...,B_r. אם לא מחזירים **INVALID**.
#מצפינים את הבלוק הראשון Y_0=E_K(B_0).
#מחשבים את תג האימות. עבור i=1 עד r מבצעים: Y_i=E_K(B_i\oplus Y_{i-1}).
#אם T = \text{MSB}_{Tlen}(Y_r) מחזירים את P אחרת מחזירים **INVALID**.

שימו לב שבמבנה זה נדרשת רק פונקציית ההצפנה של צופן הבלוקים. בעוד שפענוח מתבצע באופן דומה להצפנה באמצעות XOR כמו בצופן זרם. כדי למנוע התקפת תיזמון יש צורך לוודא שבמקרה שגיאה תוקף אפשרי לא יכול לדעת אם השגיאה ארעה בשלב 7 או 10.

### פירוט פרמטרים
משרשרים את וקטור האתחול, המידע הנלווה והמסר המיועד להצפנה למחרוזת אחת ארוכה, אותה מחלקים למקטעים בגודל 16 בתים (128 סיביות) כך שמתקבל מערך בלוקים B_0,B_1,B_2,.... כדלהלן: תחילה הבלוק הראשון B_0 מכיל אינפורמציה כללית ואת וקטור האתחול ומפורמט לפי סדר זה מהקטן לגדול: b_0,...,b_{15}, כך שהבית הראשון b_0 מכיל 'דגלים' (להלן), בתים b_1,...,b_{(15-L)} מכילים את וקטור האתחול. בתים b_{(16-L)},...,b_{15} מכילים את קידוד אורך המסר P.

הבית הראשון המכיל את הדגלים מקודד בסדר יורד כדלהלן, סיבית 8 שמורה (תמיד אפס), סיבית 7 מציינת האם קיים מידע נלווה. היא תקבע לאפס אם אורך המידע הנלווה הוא אפס. סיביות 4 עד 6 מכילות את M' לפי קידוד (M-2)/2. הערכים הקבילים הם 1 עד 7. אין להשתמש באפס כי משמעותו 16. סיביות 1 עד 3 מכילות את L' בטווח הערכים 1 עד 7 לפי קידוד L-1 כאשר אפס שמור.

אם קיים מידע נלווה A תחילה משרשרים את אורכו ואז מחלקים את הכול ביחד לבלוקים בגודל 128 סיביות ומרפדים את הבלוק האחרון באפסים אם צריך. את אורכו של המידע הנלווה מקודדים כדלהלן. שני הבתים הראשונים משמשים לזיהוי הקידוד בהתאם. אם אורך המידע הנלווה בסיביות נמוך מ-2^{16}-2^8, הוא תופס שני בתים בלבד לפי סדר בתים גדול. אם המידע הנלווה גדול יותר אך נמוך מ-2^{32}, שני הבתים הראשונים יכילו את הקבועים \text{0xff,0xfe} ואז מקודדים את אורך המידע הנלווה בארבעה בתים נוספים לפי סדר בתים גדול (סך הכול שישה בתים). אם המידע הנלווה גדול יותר (עד 2^{64} בתים), שני הבתים הראשונים יכילו את הקבועים \text{0xff,0xff} ובשמונה בתים נוספים מקודדים את אורך המידע (סך הכול עשרה בתים). הטבלה הבאה מתארת את הקידוד:





לאחר הבלוקים של המידע הנלווה משרשרים את המסר המיועד להצפנה כשהוא מחולק גם הוא לבלוקים בגודל 128 סיביות ומרופד באפסים בהתאם, והתוצאה היא מערך הבלוקים B_0,B_1,...,B_r כאשר r תלוי באורך המידע הנלווה והמסר המיועד להצפנה בהתאם פלוס הבלוק הראשון.



לדוגמה אם בלוק B_0 מכיל את מחרוזת הסיביות הבאה, 128 סיביות מחולקות לבתים משמאל לימין (הסיבית השמאלית בכל בית היא המשמעותית ביותר):



#כיוון שהסיבית לפני האחרונה בבית הראשון (המסומנת באדום) היא 1, המשמעות היא שקיים מידע נלווה.
#אורך תג האימות הוא (5+1)\cdot 2 (בגלל ששלוש הסיביות הבאות המסומנות בכחול הן "101" – 5 בייצוג עשרוני).
#היות ששלוש הסיביות הבאות (ירוק) הן "110" אורך המסר מקודד בשבעה הבתים האחרונים בסך הכול 56 סיביות.
#לפי תכולת שבעה הבתים האחרונים אורך המסר המיועד להצפנה ואימות הוא 20,000 בתים.
#וקטור האתחול מאוחסן בשמונת הבתים הנותרים (בסגול) שהם בבסיס הקסדצימלי: "13D4A35D71A50000"

### הכנת המונה
לצורך הצפנה במצב מונה (Counter mode), תחילה מייצרים בלוקים של מונה כל אחד בגודל 16 בתים. את המונה אפשר לחשב מראש לפני הגעת המסר. קידוד המונה מתבצע בדרך דומה, לפי סדר בתים גדול, הבית הראשון מכיל את הדגלים, הבתים 1...(15-L) מכילים Nonce (ערך ייחודי חד-פעמי), הבתים (16-L)...15 מכילים את המונה. הבית המכיל את הדגלים מקודד כך ששתי הסיביות המשמעותיות (7 ו-8) אינן בשימוש, הסיביות 4 עד 6 מכילות אפס והסיביות 1 עד 3 מכילות את L-1 לדוגמה \text{011} פירושו שאורך המונה הוא 4 בתים (הערך המקסימלי הוא 8 בתים). את המונה מצפינים באמצעות צופן הבלוקים והצפנת המידע עצמו מתבצעת עם המונה המוצפן שמשמש כמפתח בשיטה דומה לצופן זרם, בה מצפינים מילה אחר מילה ב-XOR.





### ביטחון
קיימת הוכחה שביטחון CCM עומד בשורה אחת עם אלגוריתמים אחרים כמו OCB. כדי שההוכחה תהיה תקפה יש להגביל את כמות המידע הניתן להצפנה עם מפתח יחיד שלא יעלה על 2^{61} בלוקים של 128 סיביות, שזה בערך 16 מיליון טרה-בית. לגבי האימות לפי הגדרת הביטחון של האלגוריתם הסיכויים שיעלה בידי תוקף לזייף טקסט מוצפן כך שאלגוריתם האימות יחזיר אמת, בלי ידיעת המפתח הסודי הוא 2^{-\mathit{Tlen}}. לכן לא רצוי להשתמש בתג הקצר מ-64 סיביות. יתרה מזו יש צורך להגביל את מספר הפעמים שהפרוטוקול יחזיר INVALID (כאשר אחד הפרמטרים שגוי) עם מפתח נתון בהתאם לסיטואציה, למשל אם רוחב הפס נמוך לא סביר שהתוקף ינסה פעמים רבות, לעומת זאת אם ביצוע הפרוטוקול מהיר יש חשש שהתוקף ינסה פעמים רבות עד שיצליח לזייף תג אימות או לפענח את המסר. בניסוח פורמלי אם מייצגים את מספר הקריאות שנכשלו (כלומר שהאלגוריתם החזיר INVALID) עם מפתח נתון MaxErrs וכן הסיכוי לזיוף מוצלח מסומן Risk אזי:
:\mathit{Tlen} \ge \text{lg}(\mathit{MaxErrs} / \mathit{Risk}).

### יתרונות וחסרונות
*האלגוריתם מספק הצפנה מאומתת מוכחת, המשלבת הצפנה במצב מונה מהירה ואימות CBC-MAC שניהם פרימיטיבים ידועים ובטוחים.
*מבנה גנרי שאינו תלוי באלגוריתמים ספציפיים, מה שמאפשר את החלפתם במידת הצורך.
*יש צורך רק בפונקציית הצפנה, הן להצפנה והן לפענוח. במקרה של AES זהו חיסכון בקוד כי פונקציית הפענוח שונה מההצפנה.
*הצפנה במצב מונה ניתנת לביצוע מקבילי, אך לא שלב האימות.
*דרוש רק מפתח הצפנה סודי יחיד שממנו נגזר מפתח האימות. למרות הסיכון שבדבר, המפתחים היו זהירים מספיק כדי למנוע פרצה.
*אפשר להכין מראש את זרם-המפתח להצפנת גוף המסר אך לא את מפתח האימות.
*התנפחות הצופן מעבר לאורך המסר המקורי היא בסדר גודל בין 4 ל-14 בתים בהתאם לגודל התג.
*אין דרישות זיכרון מיוחדות מעבר לדרישות הזיכרון של צופן הבלוקים.

לעומת זאת המבקרים מצביעים על כמה חולשות ביניהן:
*CCM אינו מנצל היטב מצב שבו המידע הנלווה אם ישנו קבוע ממסר למסר. אלא יש צורך לעבדו מחדש בכל הצפנה גם אם לא השתנה.
*אורך המסר חייב להיות ידוע מראש משום שאורך המסר מקודד בבלוק הראשון.
*הפורמט של המידע המיועד להצפנה מגושם ומסובך. בייחוד שביטחון האלגוריתם נשען בין היתר גם על הפורמט.

## ראו גם
* EAX
* OCB
* מצב הפעלה של צופן בלוקים

## קישורים חיצוניים
* 

## הערות שוליים

קטגוריה:קריפטוגרפיה